fix(jetbrains): keep the account overlay hidden after a prompted worktree start

Creating a worktree with a prompt opens the new session and dispatches the prompt in the same EDT event, so the history load resolves afterwards with no messages and fired ViewChanged.ShowEmpty. That re-showed the account overlay and wedged the view state, because showSession() early-returns once model.showSession is set, so hideAccountOverlay() could never run again and the account chip stayed on top of a running session. setControllerViewState now ignores ShowEmpty once the transcript is shown.
This commit is contained in:
kirillk
2026-08-25 09:23:50 -04:00
parent 057b48cc05
commit a2cd74bc5f
3 changed files with 39 additions and 0 deletions
@@ -2308,6 +2308,9 @@ class SessionController(
private fun setControllerViewState(event: SessionControllerEvent.ViewChanged) {
assertEdt()
if (disposed) return
// A late empty history load must not re-show the empty screen after a prompt opened the
// transcript.
if (event is SessionControllerEvent.ViewChanged.ShowEmpty && model.showSession) return
if (event is SessionControllerEvent.ViewChanged.ShowSession) openLocal()
if (viewState == event) return
fire(event) {
@@ -932,6 +932,22 @@ class SessionUiLayoutTest : SessionUiTestBase() {
assertFalse(overlay.isVisible)
}
fun `test account overlay stays hidden when prompt races empty history load`() {
appRpc.state.value = KiloAppStateDto(KiloAppStatusDto.READY, profile = ProfileDto(email = "user@example.com"))
val gate = CompletableDeferred<Unit>()
rpc.historyGate = gate
ui = newUi(id = "ses_test")
ApplicationManager.getApplication().invokeAndWait {
controller().prompt("hello")
}
gate.complete(Unit)
settle()
val overlay = find<SessionAccountOverlay>(ui)
assertFalse(overlay.isVisible)
}
fun `test non-empty explicit session does not show overlay`() {
rpc.history.add(MessageWithPartsDto(message("msg1"), emptyList()))
ui = newUi(id = "ses_test")
@@ -11,6 +11,7 @@ import ai.kilocode.rpc.dto.MessageTimeDto
import ai.kilocode.rpc.dto.MessageWithPartsDto
import ai.kilocode.rpc.dto.ModelDto
import ai.kilocode.rpc.dto.ProviderDto
import kotlinx.coroutines.CompletableDeferred
class HistoryLoadingTest : SessionControllerTestBase() {
@@ -91,6 +92,25 @@ class HistoryLoadingTest : SessionControllerTestBase() {
)
}
fun `test prompt during history load keeps the session view`() {
val gate = CompletableDeferred<Unit>()
rpc.historyGate = gate
val c = controller("ses_test")
val events = collect(c)
edt { c.prompt("hello") }
gate.complete(Unit)
flush()
assertControllerEvents("""
AccountOverlayChanged hide
AppChanged
WorkspaceChanged
ViewChanged progress
ViewChanged session
""", events)
}
fun `test loaded history derives agent from latest message`() {
appRpc.state.value = KiloAppStateDto(KiloAppStatusDto.READY, config = ConfigDto(model = "kilo/gpt-5"))
projectRpc.state.value = workspaceReady(agents = agents(), default = "plan")