mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-08-28 19:11:03 +08:00
fix(jetbrains): refine agent manager badges
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@kilocode/kilo-jetbrains": patch
|
||||
---
|
||||
|
||||
Improve JetBrains Agent Manager session status badges, selection persistence, and PR badge theming.
|
||||
+1
-1
@@ -145,7 +145,7 @@ class AgentManagerPanel(
|
||||
}
|
||||
|
||||
fun refresh() {
|
||||
selected = currentEditorWorktree()
|
||||
selected = selected ?: currentEditorWorktree()
|
||||
controller.reload()
|
||||
project?.service<WorktreeStatusService>()?.refreshStats()
|
||||
project?.service<WorktreeStatusService>()?.refreshPr()
|
||||
|
||||
+6
-1
@@ -14,6 +14,7 @@ import ai.kilocode.client.session.history.LocalHistoryItem
|
||||
import ai.kilocode.client.plugin.KiloPluginSettings
|
||||
import ai.kilocode.client.telemetry.Telemetry
|
||||
import ai.kilocode.client.ui.list.ActiveList
|
||||
import ai.kilocode.client.ui.list.ActiveListBadge
|
||||
import ai.kilocode.client.ui.list.ActiveListConfig
|
||||
import ai.kilocode.client.ui.list.ActiveListDeleteOptions
|
||||
import ai.kilocode.client.ui.list.ActiveListEditOptions
|
||||
@@ -575,7 +576,11 @@ class WorktreeSessionEditorPanel(
|
||||
return name
|
||||
}
|
||||
override val tooltip: String get() = title
|
||||
override val icon: Icon? get() = WorktreeIcons.forKind(kind)
|
||||
override val badges: List<ActiveListBadge>
|
||||
get() {
|
||||
if (deleting) return emptyList()
|
||||
return listOfNotNull(kind?.let { ActiveListBadge(it.label(), it.style()) })
|
||||
}
|
||||
override val section: String get() = HistoryTime.title(HistoryTime.section(item))
|
||||
override val search: String get() = listOf(session.title, session.id, session.directory).joinToString(" ")
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package ai.kilocode.client.ui
|
||||
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme
|
||||
import com.intellij.ui.ColorUtil
|
||||
import com.intellij.ui.JBColor
|
||||
import com.intellij.util.ui.JBFont
|
||||
import com.intellij.util.ui.JBUI
|
||||
@@ -52,6 +53,8 @@ object UiStyle {
|
||||
|
||||
/** Filled badge styles shared across JetBrains UI surfaces. */
|
||||
object Badge {
|
||||
private const val PR_SOFT_ALPHA = 0.15
|
||||
|
||||
interface Style {
|
||||
fun bg(): Color
|
||||
|
||||
@@ -145,51 +148,47 @@ object UiStyle {
|
||||
}
|
||||
|
||||
object PullRequestOpen : Style {
|
||||
override fun bg(): Color = JBColor.namedColor(
|
||||
"Kilo.PullRequest.openBadgeBackground",
|
||||
JBColor(Color(0x1F, 0x88, 0x3D), Color(0x23, 0x86, 0x36)),
|
||||
private val accent = JBColor.namedColor(
|
||||
"Kilo.PullRequest.openBadgeForeground",
|
||||
JBColor(Color(0x1A, 0x7F, 0x37), Color(0x3F, 0xB9, 0x50)),
|
||||
)
|
||||
|
||||
override fun fg(): Color = JBColor.namedColor(
|
||||
"Kilo.PullRequest.openBadgeForeground",
|
||||
Color.WHITE,
|
||||
)
|
||||
override fun bg(): Color = ColorUtil.withAlpha(accent, PR_SOFT_ALPHA)
|
||||
|
||||
override fun fg(): Color = accent
|
||||
}
|
||||
|
||||
object PullRequestDraft : Style {
|
||||
override fun bg(): Color = JBColor.namedColor(
|
||||
"Kilo.PullRequest.draftBadgeBackground",
|
||||
JBColor(Color(0x6E, 0x77, 0x81), Color(0x6E, 0x76, 0x81)),
|
||||
private val accent = JBColor.namedColor(
|
||||
"Kilo.PullRequest.draftBadgeForeground",
|
||||
JBColor(Color(0x59, 0x63, 0x6E), Color(0x91, 0x98, 0xA1)),
|
||||
)
|
||||
|
||||
override fun fg(): Color = JBColor.namedColor(
|
||||
"Kilo.PullRequest.draftBadgeForeground",
|
||||
Color.WHITE,
|
||||
)
|
||||
override fun bg(): Color = ColorUtil.withAlpha(accent, PR_SOFT_ALPHA)
|
||||
|
||||
override fun fg(): Color = accent
|
||||
}
|
||||
|
||||
object PullRequestMerged : Style {
|
||||
override fun bg(): Color = JBColor.namedColor(
|
||||
"Kilo.PullRequest.mergedBadgeBackground",
|
||||
JBColor(Color(0x82, 0x50, 0xDF), Color(0x89, 0x57, 0xE5)),
|
||||
private val accent = JBColor.namedColor(
|
||||
"Kilo.PullRequest.mergedBadgeForeground",
|
||||
JBColor(Color(0x82, 0x50, 0xDF), Color(0xA3, 0x71, 0xF7)),
|
||||
)
|
||||
|
||||
override fun fg(): Color = JBColor.namedColor(
|
||||
"Kilo.PullRequest.mergedBadgeForeground",
|
||||
Color.WHITE,
|
||||
)
|
||||
override fun bg(): Color = ColorUtil.withAlpha(accent, PR_SOFT_ALPHA)
|
||||
|
||||
override fun fg(): Color = accent
|
||||
}
|
||||
|
||||
object PullRequestClosed : Style {
|
||||
override fun bg(): Color = JBColor.namedColor(
|
||||
"Kilo.PullRequest.closedBadgeBackground",
|
||||
JBColor(Color(0xCF, 0x22, 0x2E), Color(0xDA, 0x36, 0x33)),
|
||||
private val accent = JBColor.namedColor(
|
||||
"Kilo.PullRequest.closedBadgeForeground",
|
||||
JBColor(Color(0xCF, 0x22, 0x2E), Color(0xF8, 0x51, 0x49)),
|
||||
)
|
||||
|
||||
override fun fg(): Color = JBColor.namedColor(
|
||||
"Kilo.PullRequest.closedBadgeForeground",
|
||||
Color.WHITE,
|
||||
)
|
||||
override fun bg(): Color = ColorUtil.withAlpha(accent, PR_SOFT_ALPHA)
|
||||
|
||||
override fun fg(): Color = accent
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+21
-1
@@ -233,7 +233,7 @@ class AgentManagerPanelTest : BasePlatformTestCase() {
|
||||
assertEquals(second.id, edt { (list.selectedValue as ActiveListItem).key })
|
||||
}
|
||||
|
||||
fun `test refresh selects active worktree editor`() {
|
||||
fun `test refresh keeps existing selection`() {
|
||||
val first = WorktreeDto("/repo/.kilo/worktrees/feature-x", "feature-x", "feature/x", "/repo/.kilo/worktrees/feature-x")
|
||||
val second = WorktreeDto("/repo/.kilo/worktrees/feature-y", "feature-y", "feature/y", "/repo/.kilo/worktrees/feature-y")
|
||||
rpc.listed += first
|
||||
@@ -251,6 +251,26 @@ class AgentManagerPanelTest : BasePlatformTestCase() {
|
||||
}
|
||||
flush()
|
||||
|
||||
assertEquals(first.id, edt { (list.selectedValue as ActiveListItem).key })
|
||||
}
|
||||
|
||||
fun `test refresh uses active worktree editor when no selection exists`() {
|
||||
val first = WorktreeDto("/repo/.kilo/worktrees/feature-x", "feature-x", "feature/x", "/repo/.kilo/worktrees/feature-x")
|
||||
val second = WorktreeDto("/repo/.kilo/worktrees/feature-y", "feature-y", "feature/y", "/repo/.kilo/worktrees/feature-y")
|
||||
rpc.listed += first
|
||||
rpc.listed += second
|
||||
val controller = WorktreeController(service, "/test", coroutines.scope)
|
||||
val panel = edt { AgentManagerPanel(testRootDisposable, controller, project) }
|
||||
edt { controller.reload() }
|
||||
flush()
|
||||
val list = edt { UIUtil.findComponentOfType(panel, JBList::class.java)!! }
|
||||
edt {
|
||||
ensureWorktreeSessionEditorKind()
|
||||
project.service<KiloVfsManager>().open(WorktreeSessionEditorKind.ID, worktreeSessionParams(second), focus = true)
|
||||
panel.refresh()
|
||||
}
|
||||
flush()
|
||||
|
||||
assertEquals(second.id, edt { (list.selectedValue as ActiveListItem).key })
|
||||
}
|
||||
|
||||
|
||||
+16
-4
@@ -14,9 +14,9 @@ import ai.kilocode.client.testing.FakeSessionRpcApi
|
||||
import ai.kilocode.client.testing.TestCoroutines
|
||||
import ai.kilocode.client.testing.pumpEdt
|
||||
import ai.kilocode.client.testing.fire
|
||||
import ai.kilocode.client.plugin.KiloBundle
|
||||
import ai.kilocode.client.plugin.KiloPluginSettings
|
||||
import ai.kilocode.client.ui.list.ActiveList
|
||||
import ai.kilocode.client.ui.list.ActiveListBadge
|
||||
import ai.kilocode.client.ui.list.ActiveListItem
|
||||
import ai.kilocode.client.ui.list.activeListSectionTitle
|
||||
import ai.kilocode.client.ui.list.activeListToolWindowBackground
|
||||
@@ -236,7 +236,7 @@ class WorktreeSessionEditorPanelTest : BasePlatformTestCase() {
|
||||
assertEquals("new", edt { (list.selectedValue as ActiveListItem).key })
|
||||
}
|
||||
|
||||
fun `test running session row shows the activity icon and no badge`() {
|
||||
fun `test running session row shows activity badge without leading icon`() {
|
||||
manager.kinds = mapOf("ses_1" to SessionActivityKind.RUNNING)
|
||||
val session = session("ses_1", nowSeconds())
|
||||
rpc.listed += session
|
||||
@@ -246,13 +246,25 @@ class WorktreeSessionEditorPanelTest : BasePlatformTestCase() {
|
||||
val row = row("ses_1")
|
||||
|
||||
assertEquals("Session ses_1", row.title)
|
||||
assertSame(WorktreeIcons.running, row.icon)
|
||||
assertNull(row.icon)
|
||||
assertNull(row.description)
|
||||
assertEquals(emptyList<ActiveListBadge>(), row.badges)
|
||||
assertEquals(KiloBundle.message("session.part.tool.running"), row.badges.single().text)
|
||||
assertNull(row.trailing)
|
||||
assertEquals(HistoryTime.title(HistoryTime.section(LocalHistoryItem(session))), row.section)
|
||||
}
|
||||
|
||||
fun `test plan session row shows activity badge without leading icon`() {
|
||||
manager.kinds = mapOf("ses_1" to SessionActivityKind.PLAN)
|
||||
rpc.listed += session("ses_1", nowSeconds())
|
||||
edt { controller.reload() }
|
||||
flush()
|
||||
|
||||
val row = row("ses_1")
|
||||
|
||||
assertNull(row.icon)
|
||||
assertEquals(KiloBundle.message("history.badge.plan"), row.badges.single().text)
|
||||
}
|
||||
|
||||
fun `test session row shows the live agent title over the listed placeholder`() {
|
||||
rpc.listed += session("ses_1", nowSeconds()).copy(title = "New session - 2026-07-30T19:01:40.945Z")
|
||||
edt { controller.reload() }
|
||||
|
||||
@@ -64,4 +64,18 @@ class UiStyleTest : BasePlatformTestCase() {
|
||||
assertSame(UiStyle.Badge.PullRequestMerged, style(GhState.MERGED))
|
||||
assertSame(UiStyle.Badge.PullRequestClosed, style(GhState.CLOSED))
|
||||
}
|
||||
|
||||
fun `test pull request badges use soft accent backgrounds`() {
|
||||
val styles = listOf(
|
||||
UiStyle.Badge.PullRequestOpen,
|
||||
UiStyle.Badge.PullRequestDraft,
|
||||
UiStyle.Badge.PullRequestMerged,
|
||||
UiStyle.Badge.PullRequestClosed,
|
||||
)
|
||||
|
||||
styles.forEach { style ->
|
||||
assertTrue(style.bg().alpha < Color.WHITE.alpha)
|
||||
assertEquals(Color.WHITE.alpha, style.fg().alpha)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user