diff --git a/.changeset/session-expandable-defaults.md b/.changeset/session-expandable-defaults.md new file mode 100644 index 00000000000..905b3adb933 --- /dev/null +++ b/.changeset/session-expandable-defaults.md @@ -0,0 +1,5 @@ +--- +"@kilocode/kilo-jetbrains": patch +--- + +Start expandable session sections collapsed by default. diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/header/SessionHeaderPanel.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/header/SessionHeaderPanel.kt index 615f52df59e..c1ff05c96d5 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/header/SessionHeaderPanel.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/header/SessionHeaderPanel.kt @@ -391,7 +391,7 @@ class SessionHeaderPanel( expand.accessibleContext.accessibleName = KiloBundle.message(key) } - private fun expanded() = PropertiesComponent.getInstance().getBoolean(EXPANDED_KEY, true) + private fun expanded() = PropertiesComponent.getInstance().getBoolean(EXPANDED_KEY, false) private fun sizeTimeline() { val size = timeline.preferredSize diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/ReasoningView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/ReasoningView.kt index bec8c6b6fad..709264e5ad5 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/ReasoningView.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/ReasoningView.kt @@ -109,7 +109,6 @@ class ReasoningView(reasoning: Reasoning) : PartView() { body.add(md.component, BorderLayout.CENTER) add(header, BorderLayout.NORTH) - if (canExpand()) add(scroll, BorderLayout.CENTER) sync() } @@ -122,7 +121,6 @@ class ReasoningView(reasoning: Reasoning) : PartView() { md.set(source) changed = true } - changed = syncBody() || changed changed = sync() || changed if (changed) refresh() } @@ -131,8 +129,7 @@ class ReasoningView(reasoning: Reasoning) : PartView() { if (delta.isEmpty()) return source += delta md.append(delta) - var changed = syncBody() - changed = sync() || changed + val changed = sync() if (changed || bodyVisible()) refresh() } @@ -209,12 +206,6 @@ class ReasoningView(reasoning: Reasoning) : PartView() { return changed } - private fun syncBody(): Boolean { - if (!canExpand()) return collapse() - if (bodyVisible()) return false - return expand() - } - private fun setVisible(component: JBLabel, visible: Boolean): Boolean { if (component.isVisible == visible) return false component.isVisible = visible diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/header/SessionHeaderPanelTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/header/SessionHeaderPanelTest.kt index 217c8ca94d2..361d1846e1c 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/header/SessionHeaderPanelTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/header/SessionHeaderPanelTest.kt @@ -54,7 +54,7 @@ class SessionHeaderPanelTest : SessionControllerTestBase() { val style = SessionEditorStyle.current() assertTrue(panel.isVisible) - assertTrue(panel.isExpanded()) + assertFalse(panel.isExpanded()) assertEquals("Generated title", panel.titleText()) assertEquals("$0.07", panel.costText()) assertEquals("1%", panel.contextText()) @@ -135,6 +135,9 @@ class SessionHeaderPanelTest : SessionControllerTestBase() { val timeline = panel.timelinePanel() val bar = panel.contextBar() + assertFalse(panel.isExpanded()) + panel.expandButton().doClick() + assertTrue(panel.isExpanded()) assertSame(body, panel.bodyPanel()) assertSame(timeline, panel.timelinePanel()) @@ -244,26 +247,27 @@ class SessionHeaderPanelTest : SessionControllerTestBase() { val c = promptedHeader() val panel = SessionHeaderPanel(c, parent) - assertTrue(panel.isExpanded()) - assertEquals("Hide session metrics", panel.expandTip()) - - panel.expandButton().doClick() - emit(ChatEventDto.SessionUpdated("ses_test", session("ses_test", title = "New title"))) - assertFalse(panel.isExpanded()) assertEquals("Show session metrics", panel.expandTip()) panel.expandButton().doClick() - emit(ChatEventDto.MessageUpdated("ses_test", assistant(cost = 0.2))) + emit(ChatEventDto.SessionUpdated("ses_test", session("ses_test", title = "New title"))) assertTrue(panel.isExpanded()) assertEquals("Hide session metrics", panel.expandTip()) + + panel.expandButton().doClick() + emit(ChatEventDto.MessageUpdated("ses_test", assistant(cost = 0.2))) + + assertFalse(panel.isExpanded()) + assertEquals("Show session metrics", panel.expandTip()) } fun `test collapse persists and new header starts collapsed`() { val c = promptedHeader() val panel = SessionHeaderPanel(c, parent) + panel.expandButton().doClick() panel.expandButton().doClick() assertFalse(panel.isExpanded()) @@ -294,6 +298,7 @@ class SessionHeaderPanelTest : SessionControllerTestBase() { } fun `test hidden empty header collapse keeps saved expansion preference`() { + PropertiesComponent.getInstance().setValue(SessionHeaderPanel.EXPANDED_KEY, "true") appRpc.state.value = ai.kilocode.rpc.dto.KiloAppStateDto(ai.kilocode.rpc.dto.KiloAppStatusDto.READY) projectRpc.state.value = workspaceReady() val c = controller() diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ReasoningViewTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ReasoningViewTest.kt index 6cae7834def..f0cf4d20169 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ReasoningViewTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ReasoningViewTest.kt @@ -8,61 +8,58 @@ import javax.swing.ScrollPaneConstants @Suppress("UnstableApiUsage") class ReasoningViewTest : BasePlatformTestCase() { - fun `test completed reasoning is expanded by default`() { + fun `test completed reasoning is collapsed by default`() { val view = ReasoningView(reasoning("p1", done = true, text = "one\ntwo\nthree\nfour")) - assertTrue(view.isExpanded()) + assertFalse(view.isExpanded()) assertEquals("Reasoning", view.headerText()) assertEquals("one\ntwo\nthree\nfour", view.markdown()) assertTrue(view.hasToggle()) - assertTrue(view.bodyVisible()) + assertFalse(view.bodyVisible()) assertTrue(view.bodyCreated()) } fun `test short completed reasoning is collapsible`() { val view = ReasoningView(reasoning("p1", done = true, text = "one\ntwo\nthree")) - assertTrue(view.isExpanded()) + assertFalse(view.isExpanded()) assertTrue(view.hasToggle()) view.toggle() - assertFalse(view.isExpanded()) - assertFalse(view.bodyVisible()) + assertTrue(view.isExpanded()) + assertTrue(view.bodyVisible()) assertTrue(view.bodyCreated()) } - fun `test streaming reasoning is expanded by default`() { + fun `test streaming reasoning is collapsed by default`() { val view = ReasoningView(reasoning("p1", done = false, text = "one\ntwo\nthree\nfour")) - assertTrue(view.isExpanded()) + assertFalse(view.isExpanded()) assertTrue(view.hasToggle()) } - fun `test update to done preserves visible reasoning`() { + fun `test update to done preserves collapsed reasoning`() { val view = ReasoningView(reasoning("p1", done = false, text = "one\ntwo\nthree\nfour")) view.update(reasoning("p1", done = true, text = "one\ntwo\nthree\nfour")) - assertTrue(view.isExpanded()) + assertFalse(view.isExpanded()) assertEquals("one\ntwo\nthree\nfour", view.markdown()) } fun `test toggle opens and closes reasoning`() { val view = ReasoningView(reasoning("p1", done = true, text = "one\ntwo\nthree\nfour")) + view.toggle() assertTrue(view.isExpanded()) view.toggle() assertFalse(view.isExpanded()) - view.toggle() - assertTrue(view.isExpanded()) } - fun `test collapsed reasoning expands on update`() { + fun `test collapsed reasoning stays collapsed on update`() { val view = ReasoningView(reasoning("p1", done = false, text = "one\ntwo")) - - view.toggle() view.update(reasoning("p1", done = true, text = "one\ntwo\nthree")) - assertTrue(view.isExpanded()) + assertFalse(view.isExpanded()) assertEquals("one\ntwo\nthree", view.markdown()) } @@ -72,39 +69,38 @@ class ReasoningViewTest : BasePlatformTestCase() { view.appendDelta("b") assertEquals("ab", view.markdown()) - assertTrue(view.isExpanded()) + assertFalse(view.isExpanded()) } - fun `test blank reasoning expands when delta arrives`() { + fun `test blank reasoning stays collapsed when delta arrives`() { val view = ReasoningView(reasoning("p1", done = false, text = "")) view.appendDelta("b") assertEquals("b", view.markdown()) assertTrue(view.bodyCreated()) - assertTrue(view.bodyVisible()) + assertFalse(view.bodyVisible()) + assertTrue(view.hasToggle()) } - fun `test collapsed append reattaches eager reasoning body`() { + fun `test collapsed append keeps eager reasoning body detached`() { val view = ReasoningView(reasoning("p1", done = false, text = "a")) - view.toggle() view.appendDelta("b") assertEquals("ab", view.markdown()) assertTrue(view.bodyCreated()) - assertTrue(view.bodyVisible()) + assertFalse(view.bodyVisible()) } - fun `test collapsed update reattaches eager reasoning body`() { + fun `test collapsed update keeps eager reasoning body detached`() { val view = ReasoningView(reasoning("p1", done = false, text = "a")) - view.toggle() view.update(reasoning("p1", done = false, text = "abc")) assertEquals("abc", view.markdown()) assertTrue(view.bodyCreated()) - assertTrue(view.bodyVisible()) + assertFalse(view.bodyVisible()) } fun `test reasoning reuses eager markdown body`() { @@ -116,7 +112,7 @@ class ReasoningViewTest : BasePlatformTestCase() { view.toggle() assertSame(component, view.md.component) - assertFalse(view.bodyVisible()) + assertTrue(view.bodyVisible()) } fun `test blank reasoning has no toggle`() { @@ -158,6 +154,7 @@ class ReasoningViewTest : BasePlatformTestCase() { fun `test expanded reasoning body is capped to five rows`() { val view = ReasoningView(reasoning("p1", done = false, text = (1..20).joinToString("\n") { "line $it" })) + view.toggle() assertEquals(5, view.bodyMaxRows()) assertTrue(view.preferredSize.height > 0)