chore: upgrade ktlint to 1.8.0 and format codebase (#1024)

Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
M57andM57 authored and GitHub committed 2026-08-31 12:27:40 +03:00
1 parent 3f3b853758
commit cfe3e736fd
66 files changed
+1287 -541

No files matched your search

@@ -158,7 +158,13 @@ class ChatInputPolicyTest {
@Test
fun applyMention_insertsHandleAndAdvancesCursor() {
val initial = TextFieldValue("ask @sc", selection = androidx.compose.ui.text.TextRange(7))
val initial =
TextFieldValue(
"ask @sc",
selection =
androidx.compose.ui.text
.TextRange(7),
)
val updated = ChatInputPolicy.applyMention(initial, "scout")
assertEquals("ask @scout ", updated.text)
assertEquals(11, updated.selection.end)
@@ -369,12 +369,13 @@ class ChatToolDedupeTest {
var stream = StreamingState()
stream = ChatWsEventReducer.reduce(s, stream, WsEvent.MessageStart("session-1"), "session-1").streamingState
stream =
ChatWsEventReducer.reduce(
s,
stream,
WsEvent.ReasoningDelta("thinking about meow", "session-1"),
"session-1",
).streamingState
ChatWsEventReducer
.reduce(
s,
stream,
WsEvent.ReasoningDelta("thinking about meow", "session-1"),
"session-1",
).streamingState
var r =
ChatWsEventReducer.reduce(
s,
@@ -159,7 +159,12 @@ class ChatUpdateCommandTest {
advanceUntilIdle()
assertTrue("confirm dialog should open", vm.uiState.value.updateConfirmOpen)
assertEquals("/update", vm.uiState.value.messages.last().content)
assertEquals(
"/update",
vm.uiState.value.messages
.last()
.content,
)
// The whole point of the fix: NOTHING goes over the wire.
verify(exactly = 0) {
@@ -513,7 +513,10 @@ class ChatViewModelTest {
// A blocklisted command can never dispatch — it must not climb
// the autocomplete ranking either.
assertTrue(viewModel.uiState.value.slashUsageCounts.isEmpty())
assertTrue(
viewModel.uiState.value.slashUsageCounts
.isEmpty(),
)
verify(exactly = 0) {
HermesWsClient.request(WsMethods.COMMAND_DISPATCH, any(), any())
}
@@ -1033,7 +1036,10 @@ class ChatViewModelTest {
viewModel.uiState.value.messages[1]
.role,
)
assertFalse(viewModel.uiState.value.messages[1].isStreaming)
assertFalse(
viewModel.uiState.value.messages[1]
.isStreaming,
)
assertEquals(
MessageRole.TOOL,
viewModel.uiState.value.messages[2]
@@ -1041,7 +1047,10 @@ class ChatViewModelTest {
)
assertNull(viewModel.streamingState.value.streamingMessage)
assertEquals(
listOf(viewModel.uiState.value.messages[1].id),
listOf(
viewModel.uiState.value.messages[1]
.id,
),
viewModel.streamingState.value.sealedOrphanIds,
)
@@ -1050,7 +1059,8 @@ class ChatViewModelTest {
mockEventsFlow.emit(WsEvent.MessageComplete("Calculating sum = 4", sessionId))
advanceUntilIdle()
val assistant =
viewModel.uiState.value.messages.filter { it.role == MessageRole.ASSISTANT }
viewModel.uiState.value.messages
.filter { it.role == MessageRole.ASSISTANT }
assertEquals(2, assistant.size)
assertEquals("Calculating sum", assistant[0].content)
assertEquals(" = 4", assistant[1].content)
@@ -1573,7 +1583,8 @@ class ChatViewModelTest {
every { AuthManager.getBaseUrl() } returns "http://test.local/"
coEvery { mockApi.getSessions(any(), any(), any()) } returns
retrofit2.Response.success(
com.m57.hermescontrol.data.model.SessionListResponse(sessions = emptyList(), total = 0),
com.m57.hermescontrol.data.model
.SessionListResponse(sessions = emptyList(), total = 0),
)
coEvery {
mockApi.getSessionMessages(
@@ -1623,7 +1634,8 @@ class ChatViewModelTest {
val empty =
retrofit2.Response.success(
com.m57.hermescontrol.data.model.SessionMessagesResponse(messages = emptyList()),
com.m57.hermescontrol.data.model
.SessionMessagesResponse(messages = emptyList()),
)
messagesA.complete(empty)
messagesB.complete(empty)
@@ -1641,7 +1653,8 @@ class ChatViewModelTest {
every { AuthManager.getBaseUrl() } returns "http://test.local/"
coEvery { mockApi.getSessions(any(), any(), any()) } returns
retrofit2.Response.success(
com.m57.hermescontrol.data.model.SessionListResponse(sessions = emptyList(), total = 0),
com.m57.hermescontrol.data.model
.SessionListResponse(sessions = emptyList(), total = 0),
)
coEvery {
mockApi.getSessionMessages(
@@ -1698,7 +1711,11 @@ class ChatViewModelTest {
advanceUntilIdle()
assertEquals("session-b", viewModel.uiState.value.currentSessionId)
assertEquals(listOf("message-b"), viewModel.uiState.value.messages.map { it.content })
assertEquals(
listOf("message-b"),
viewModel.uiState.value.messages
.map { it.content },
)
}
@Test
@@ -1927,7 +1944,8 @@ class ChatViewModelTest {
sessionIds.forEach { sessionId ->
coEvery { mockApi.getSessionMessages(sessionId, any(), any(), any(), any()) } returns
retrofit2.Response.success(
com.m57.hermescontrol.data.model.SessionMessagesResponse(messages = emptyList()),
com.m57.hermescontrol.data.model
.SessionMessagesResponse(messages = emptyList()),
)
}
}
@@ -1956,7 +1974,11 @@ class ChatViewModelTest {
// Warm cache painted and survived the exhausted retry cycle — the
// screen never went blank, and the user gets history + an error.
assertEquals(1, viewModel.uiState.value.messages.size)
assertEquals("Cached hello", viewModel.uiState.value.messages[0].content)
assertEquals(
"Cached hello",
viewModel.uiState.value.messages[0]
.content,
)
assertFalse(viewModel.uiState.value.isLoading)
assertNotNull("resumeError must be set after retries exhaust", viewModel.uiState.value.resumeError)
assertFalse(viewModel.uiState.value.isResumeRetrying)
@@ -2305,7 +2327,8 @@ class ChatViewModelTest {
assertEquals("session-new", viewModel.uiState.value.currentSessionId)
assertTrue(
"recovery notice must be visible",
viewModel.uiState.value.messages.any { it.content.contains("no longer available") },
viewModel.uiState.value.messages
.any { it.content.contains("no longer available") },
)
}
@@ -2328,7 +2351,8 @@ class ChatViewModelTest {
ApiClient.hermesApi.getSessionMessages(capture(fetchedSessions), any(), any(), any(), any())
} returns
retrofit2.Response.success(
com.m57.hermescontrol.data.model.SessionMessagesResponse(messages = emptyList()),
com.m57.hermescontrol.data.model
.SessionMessagesResponse(messages = emptyList()),
)
// /fork sends session.branch keyed on the runtime id.
@@ -2379,7 +2403,8 @@ class ChatViewModelTest {
)
} else {
retrofit2.Response.success(
com.m57.hermescontrol.data.model.SessionMessagesResponse(messages = emptyList()),
com.m57.hermescontrol.data.model
.SessionMessagesResponse(messages = emptyList()),
)
}
}
@@ -3301,7 +3326,12 @@ class ChatViewModelTest {
assertTrue(viewModel.uiState.value.hasOlderMessages)
assertEquals(150, viewModel.uiState.value.messages.size)
// Stable keys come from the server row id, not the from-end position.
assertEquals("rest-session-456-150", viewModel.uiState.value.messages.last().id)
assertEquals(
"rest-session-456-150",
viewModel.uiState.value.messages
.last()
.id,
)
}
@Test
@@ -3444,7 +3474,10 @@ class ChatViewModelTest {
// 160 rows: the 10 new ones appended, the existing 150 kept —
// no duplicates, no dropped newest copy (stable row-id keys).
assertEquals(160, viewModel.uiState.value.messages.size)
assertTrue(viewModel.uiState.value.messages.any { it.id == "rest-session-456-160" })
assertTrue(
viewModel.uiState.value.messages
.any { it.id == "rest-session-456-160" },
)
}
// ── Attachment open (issue #724) ─────────────────────────────────────
@@ -3506,15 +3539,17 @@ class ChatViewModelTest {
runTest {
mockkObject(GatewayFileClient)
val cacheDir =
java.io.File(
System.getProperty("java.io.tmpdir"),
"gw_save_${System.nanoTime()}",
).apply { mkdirs() }
java.io
.File(
System.getProperty("java.io.tmpdir"),
"gw_save_${System.nanoTime()}",
).apply { mkdirs() }
every { app.cacheDir } returns cacheDir
every { app.applicationContext } returns app
every { app.getApplicationContext() } returns app
val file =
java.io.File(System.getProperty("java.io.tmpdir"), "note_${System.nanoTime()}.txt")
java.io
.File(System.getProperty("java.io.tmpdir"), "note_${System.nanoTime()}.txt")
.apply { writeText("downloaded") }
coEvery { GatewayFileClient.fetch("/tmp/note.txt", any()) } returns
GatewayFileResult.Success(GatewayFile("note.txt", "text/plain", file))
@@ -3552,10 +3587,11 @@ class ChatViewModelTest {
runTest {
mockkObject(GatewayFileClient)
val cacheDir =
java.io.File(
System.getProperty("java.io.tmpdir"),
"gw_save_${System.nanoTime()}",
).apply { mkdirs() }
java.io
.File(
System.getProperty("java.io.tmpdir"),
"gw_save_${System.nanoTime()}",
).apply { mkdirs() }
every { app.cacheDir } returns cacheDir
every { app.applicationContext } returns app
every { app.getApplicationContext() } returns app
@@ -3590,10 +3626,11 @@ class ChatViewModelTest {
runTest {
mockkObject(GatewayFileClient)
val cacheDir =
java.io.File(
System.getProperty("java.io.tmpdir"),
"gw_save_${System.nanoTime()}",
).apply { mkdirs() }
java.io
.File(
System.getProperty("java.io.tmpdir"),
"gw_save_${System.nanoTime()}",
).apply { mkdirs() }
every { app.cacheDir } returns cacheDir
every { app.applicationContext } returns app
every { app.getApplicationContext() } returns app
@@ -3606,7 +3643,8 @@ class ChatViewModelTest {
GatewayFile(
"report.pdf",
"application/pdf",
java.io.File(System.getProperty("java.io.tmpdir"), "report_${System.nanoTime()}.pdf")
java.io
.File(System.getProperty("java.io.tmpdir"), "report_${System.nanoTime()}.pdf")
.apply { writeBytes(byteArrayOf(1)) },
),
)
@@ -3625,7 +3663,11 @@ class ChatViewModelTest {
verify(exactly = 0) { resolver.delete(any(), any(), any()) }
assertNull(viewModel.uiState.value.savingAttachmentPath)
assertTrue(viewModel.uiState.value.openError.orEmpty().startsWith("Could not save"))
assertTrue(
viewModel.uiState.value.openError
.orEmpty()
.startsWith("Could not save"),
)
}
@Test
@@ -3633,10 +3675,11 @@ class ChatViewModelTest {
runTest {
mockkObject(GatewayFileClient)
val cacheDir =
java.io.File(
System.getProperty("java.io.tmpdir"),
"gw_save_${System.nanoTime()}",
).apply { mkdirs() }
java.io
.File(
System.getProperty("java.io.tmpdir"),
"gw_save_${System.nanoTime()}",
).apply { mkdirs() }
every { app.cacheDir } returns cacheDir
every { app.applicationContext } returns app
every { app.getApplicationContext() } returns app
@@ -3675,10 +3718,11 @@ class ChatViewModelTest {
runTest {
mockkObject(GatewayFileClient)
val cacheDir =
java.io.File(
System.getProperty("java.io.tmpdir"),
"gw_open_${System.nanoTime()}",
).apply { mkdirs() }
java.io
.File(
System.getProperty("java.io.tmpdir"),
"gw_open_${System.nanoTime()}",
).apply { mkdirs() }
every { app.cacheDir } returns cacheDir
every { app.applicationContext } returns app
every { app.getApplicationContext() } returns app
@@ -3711,10 +3755,11 @@ class ChatViewModelTest {
runTest {
mockkObject(GatewayFileClient)
val cacheDir =
java.io.File(
System.getProperty("java.io.tmpdir"),
"gw_open_${System.nanoTime()}",
).apply { mkdirs() }
java.io
.File(
System.getProperty("java.io.tmpdir"),
"gw_open_${System.nanoTime()}",
).apply { mkdirs() }
every { app.cacheDir } returns cacheDir
every { app.applicationContext } returns app
every { app.getApplicationContext() } returns app
@@ -3743,7 +3788,11 @@ class ChatViewModelTest {
// …and cleared in all outcomes.
assertNull(vm.uiState.value.openingAttachmentPath)
assertTrue(vm.uiState.value.openError.orEmpty().contains("big.pdf"))
assertTrue(
vm.uiState.value.openError
.orEmpty()
.contains("big.pdf"),
)
}
@Test
@@ -3763,7 +3812,10 @@ class ChatViewModelTest {
advanceUntilIdle()
// Optimistic UI state has the user message immediately
assertTrue(vm.uiState.value.messages.any { it.content == "My super important long prompt" })
assertTrue(
vm.uiState.value.messages
.any { it.content == "My super important long prompt" },
)
assertTrue(vm.uiState.value.isAgentTyping)
// But wsClient.sendMessage not dispatched yet because session_id was null
assertTrue(sentPrompts.isEmpty())
@@ -3781,7 +3833,10 @@ class ChatViewModelTest {
// Prompt should be dispatched automatically!
assertEquals(listOf("My super important long prompt"), sentPrompts)
assertEquals("session-storage-969", vm.uiState.value.currentSessionId)
assertTrue(vm.uiState.value.messages.any { it.content == "My super important long prompt" })
assertTrue(
vm.uiState.value.messages
.any { it.content == "My super important long prompt" },
)
}
@Test
@@ -3806,7 +3861,10 @@ class ChatViewModelTest {
advanceUntilIdle()
// Optimistic message in UI
assertTrue(vm.uiState.value.messages.any { it.content == "Prompt typed during reconnect" })
assertTrue(
vm.uiState.value.messages
.any { it.content == "Prompt typed during reconnect" },
)
// Complete the new SESSION_CREATE RPC
mockEventsFlow.emit(
@@ -3842,6 +3900,9 @@ class ChatViewModelTest {
assertFalse(vm.uiState.value.isAgentTyping)
assertNotNull(vm.uiState.value.errorMessage)
assertTrue(vm.uiState.value.errorMessage!!.contains("Backend exploded"))
assertTrue(
vm.uiState.value.errorMessage!!
.contains("Backend exploded"),
)
}
}
@@ -421,7 +421,12 @@ class ChatWsEventReducerTest {
)
assertEquals(1, result.state.messages.size)
assertEquals("complete", result.state.messages.single().content)
assertEquals(
"complete",
result.state.messages
.single()
.content,
)
}
@Test
@@ -556,12 +561,13 @@ class ChatWsEventReducerTest {
var reasoningState = start.streamingState
for (token in reasoningTokens) {
reasoningState =
ChatWsEventReducer.reduce(
state,
reasoningState,
WsEvent.ReasoningDelta(token, "session-1"),
"session-1",
).streamingState
ChatWsEventReducer
.reduce(
state,
reasoningState,
WsEvent.ReasoningDelta(token, "session-1"),
"session-1",
).streamingState
}
assertEquals(true, reasoningState.isReasoning)
assertEquals("The user just said \"run echo hi\". Let me run it.", reasoningState.reasoningText)
@@ -578,8 +584,18 @@ class ChatWsEventReducerTest {
"session-1",
)
assertEquals(1, result.state.messages.size)
assertEquals(MessageRole.TOOL, result.state.messages.first().role)
assertEquals("terminal", result.state.messages.first().toolName)
assertEquals(
MessageRole.TOOL,
result.state.messages
.first()
.role,
)
assertEquals(
"terminal",
result.state.messages
.first()
.toolName,
)
// Issue #771: streaming message + reasoning survive the tool call
assertEquals(true, result.streamingState.streamingMessage?.isStreaming)
assertEquals("The user just said \"run echo hi\". Let me run it.", result.streamingState.reasoningText)
@@ -592,7 +608,12 @@ class ChatWsEventReducerTest {
WsEvent.ToolComplete("terminal", mapOf("output" to "hi"), "session-1"),
"session-1",
)
assertEquals(ToolStatus.COMPLETED, result.state.messages.first().toolStatus)
assertEquals(
ToolStatus.COMPLETED,
result.state.messages
.first()
.toolStatus,
)
// 5. reasoning.available — authoritative full-trace fill
val fullReasoning = "The user just said \"run echo hi\". That's a simple terminal command. Let me just run it."
@@ -683,7 +704,12 @@ class ChatWsEventReducerTest {
"session-1",
)
assertEquals("payload reasoning", result.state.messages.last().reasoningText)
assertEquals(
"payload reasoning",
result.state.messages
.last()
.reasoningText,
)
}
@Test
@@ -223,7 +223,8 @@ class SlashCommandDispatchRpcTest {
// The optimistic bubble shows the queued TEXT (prefix stripped) so
// the transcript sync dedupes it against the server echo.
val userBubble =
vm.uiState.value.messages.lastOrNull { it.role == MessageRole.USER }
vm.uiState.value.messages
.lastOrNull { it.role == MessageRole.USER }
assertEquals("do the thing", userBubble?.content)
}
@@ -247,7 +248,9 @@ class SlashCommandDispatchRpcTest {
vm.sendMessage("/queue")
advanceUntilIdle()
val last = vm.uiState.value.messages.lastOrNull()
val last =
vm.uiState.value.messages
.lastOrNull()
assertEquals("usage: /queue <prompt>", last?.content)
assertEquals(0, sendCalls)
assertTrue(
@@ -628,7 +631,9 @@ class SlashCommandDispatchRpcTest {
vm.sendMessage("/focus on")
advanceUntilIdle()
val last = vm.uiState.value.messages.lastOrNull()
val last =
vm.uiState.value.messages
.lastOrNull()
assertEquals("Focus view: ON (tool progress pinned off)", last?.content)
}
}