fix(jetbrains): avoid verifier-blocked API usage

This commit is contained in:
kirillk
2026-08-18 11:25:02 -04:00
parent eb3f470292
commit 8ae524becc
6 changed files with 92 additions and 4 deletions
@@ -96,7 +96,8 @@ class KiloWorktreeRpcApiImpl : KiloWorktreeRpcApi {
return true
}
LOG.info("worktree open (backend): opening dir=$dir newFrame=true")
val project = ProjectUtil.openOrImportAsync(dir, OpenProjectTask { forceOpenInNewFrame = true })
val opts = OpenProjectTask.build().withForceOpenInNewFrame(true)
val project = ProjectUtil.openOrImportAsync(dir, opts)
LOG.info("worktree open (backend) requested: dir=$dir newFrame=true opened=${project?.name}")
return true
}
@@ -9,6 +9,7 @@ import ai.kilocode.client.telemetry.Telemetry
import ai.kilocode.client.agentManager.worktree.KiloWorktreeService
import ai.kilocode.client.agentManager.SidePanelKeys
import ai.kilocode.client.agentManager.SidePanelMode
import ai.kilocode.client.agentManager.applySidePanelMode
import ai.kilocode.client.agentManager.worktree.WorktreeController
import ai.kilocode.client.agentManager.AgentManagerPanel
import ai.kilocode.client.plugin.KiloBundle
@@ -126,9 +127,11 @@ internal class KiloToolWindowSetupService(
val factory = ContentFactory.getInstance()
val chatContent = factory.createContent(chat, KiloBundle.message("sidePanel.mode.branch"), false)
chatContent.applySidePanelMode(SidePanelMode.CHAT)
chatContent.setDisposer(manager)
chatContent.setPreferredFocusedComponent { manager.defaultFocusedComponent }
val agentContent = factory.createContent(agent, KiloBundle.message("sidePanel.mode.agentManager"), false)
agentContent.applySidePanelMode(SidePanelMode.AGENT_MANAGER)
agentContent.applyAgentManagerBetaBadge()
agentContent.setPreferredFocusedComponent { agentManagerPanel.component }
toolWindow.contentManager.addContent(chatContent)
@@ -8,7 +8,6 @@ import ai.kilocode.client.agentManager.SidePanelMode
import com.intellij.icons.AllIcons
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.DataProvider
import com.intellij.openapi.actionSystem.PlatformDataKeys
import com.intellij.openapi.project.DumbAware
import com.intellij.ui.content.Content
@@ -35,7 +34,7 @@ class HistoryAction : AnAction(
private fun selectChat(e: AnActionEvent) {
val manager = e.getData(PlatformDataKeys.TOOL_WINDOW)?.contentManager ?: return
val chat = manager.contents.firstOrNull {
(it.component as? DataProvider)?.getData(SidePanelKeys.MODE.name) == SidePanelMode.CHAT
it.getUserData(SidePanelKeys.CONTENT_MODE) == SidePanelMode.CHAT
} ?: return
manager.setSelectedContent(chat, true)
}
@@ -1,10 +1,17 @@
package ai.kilocode.client.agentManager
import com.intellij.openapi.actionSystem.DataKey
import com.intellij.openapi.util.Key
import com.intellij.ui.content.Content
enum class SidePanelMode { CHAT, AGENT_MANAGER }
object SidePanelKeys {
val MODE: DataKey<SidePanelMode> = DataKey.create("kilo.sidePanel.mode")
val WORKTREE_PANEL: DataKey<AgentManagerPanel> = DataKey.create("kilo.sidePanel.worktreePanel")
val CONTENT_MODE: Key<SidePanelMode> = Key.create("kilo.sidePanel.content.mode")
}
internal fun Content.applySidePanelMode(mode: SidePanelMode) {
putUserData(SidePanelKeys.CONTENT_MODE, mode)
}
@@ -1,5 +1,8 @@
package ai.kilocode.client
import ai.kilocode.client.agentManager.SidePanelKeys
import ai.kilocode.client.agentManager.SidePanelMode
import ai.kilocode.client.agentManager.applySidePanelMode
import ai.kilocode.client.util.edtWait
import com.intellij.icons.AllIcons
import com.intellij.openapi.wm.ToolWindow
@@ -20,4 +23,12 @@ class KiloToolWindowFactoryTest : BasePlatformTestCase() {
assertEquals(true, content.getUserData(ToolWindow.SHOW_CONTENT_ICON))
assertEquals(ComponentOrientation.RIGHT_TO_LEFT, content.getUserData(Content.TAB_LABEL_ORIENTATION_KEY))
}
fun `test content records side panel mode`() = edtWait {
val content = ContentFactory.getInstance().createContent(JPanel(), "Branch", false)
content.applySidePanelMode(SidePanelMode.CHAT)
assertEquals(SidePanelMode.CHAT, content.getUserData(SidePanelKeys.CONTENT_MODE))
}
}
@@ -1,5 +1,8 @@
package ai.kilocode.client.actions
import ai.kilocode.client.agentManager.SidePanelKeys
import ai.kilocode.client.agentManager.SidePanelMode
import ai.kilocode.client.agentManager.applySidePanelMode
import ai.kilocode.client.app.KiloSessionService
import ai.kilocode.client.app.KiloWorkspaceService
import ai.kilocode.client.app.Workspace
@@ -15,6 +18,7 @@ import ai.kilocode.client.testing.FakeSessionRpcApi
import ai.kilocode.client.testing.FakeWorkspaceRpcApi
import ai.kilocode.client.testing.TestCoroutines
import ai.kilocode.client.testing.pumpEdt
import ai.kilocode.client.util.edtWait
import ai.kilocode.rpc.dto.CloudSessionDto
import ai.kilocode.rpc.dto.KiloWorkspaceStateDto
import ai.kilocode.rpc.dto.KiloWorkspaceStatusDto
@@ -24,9 +28,15 @@ import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.ex.ActionUtil
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.actionSystem.PlatformDataKeys
import com.intellij.openapi.actionSystem.Presentation
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.wm.ToolWindow
import com.intellij.testFramework.fixtures.BasePlatformTestCase
import com.intellij.ui.content.ContentFactory
import com.intellij.ui.content.ContentManager
import java.lang.reflect.Proxy
import javax.swing.JPanel
@Suppress("UnstableApiUsage")
class HistorySessionActionsTest : BasePlatformTestCase() {
@@ -326,6 +336,30 @@ class HistorySessionActionsTest : BasePlatformTestCase() {
assertTrue(renamed.isEmpty())
}
fun `test history action selects chat content from agent manager`() = edtWait {
val action = HistoryAction()
val content = ContentFactory.getInstance().createContentManager(false, project)
try {
val chat = ContentFactory.getInstance().createContent(JPanel(), "Branch", false)
val agent = ContentFactory.getInstance().createContent(JPanel(), "Agent Manager", false)
chat.applySidePanelMode(SidePanelMode.CHAT)
agent.applySidePanelMode(SidePanelMode.AGENT_MANAGER)
content.addContent(chat)
content.addContent(agent)
content.setSelectedContent(agent)
val event = event(action, manager, content)
action.actionPerformed(event)
assertSame(chat, content.selectedContent)
assertEquals(1, manager.history)
manager.back?.invoke()
assertSame(agent, content.selectedContent)
} finally {
Disposer.dispose(content)
}
}
fun `test frontend descriptor registers history actions`() {
val xml = javaClass.classLoader.getResourceAsStream("kilo.jetbrains.frontend.xml")
?.bufferedReader()
@@ -387,6 +421,32 @@ class HistorySessionActionsTest : BasePlatformTestCase() {
return AnActionEvent.createFromDataContext("", presentation, context)
}
private fun event(
action: com.intellij.openapi.actionSystem.AnAction,
manager: SessionManager,
content: ContentManager,
): AnActionEvent {
val presentation = Presentation().apply { copyFrom(action.templatePresentation) }
val tool = Proxy.newProxyInstance(
ToolWindow::class.java.classLoader,
arrayOf(ToolWindow::class.java),
) { _, method, _ ->
when (method.name) {
"getContentManager" -> content
else -> error("unexpected ToolWindow method ${method.name}")
}
} as ToolWindow
val context = DataContext { id ->
when {
SessionManager.KEY.`is`(id) -> manager
SidePanelKeys.MODE.`is`(id) -> SidePanelMode.AGENT_MANAGER
PlatformDataKeys.TOOL_WINDOW.`is`(id) -> tool
else -> null
}
}
return AnActionEvent.createFromDataContext("", presentation, context)
}
private fun selection(
source: HistorySource,
local: List<LocalHistoryItem>,
@@ -428,8 +488,15 @@ class HistorySessionActionsTest : BasePlatformTestCase() {
}
private class FakeManager : SessionManager {
var history = 0
var back: (() -> Unit)? = null
override fun newSession() {}
override fun showHistory(back: (() -> Unit)?) {}
override fun showHistory(back: (() -> Unit)?) {
history++
this.back = back
}
override fun openSession(ref: SessionRef) {}
}
}