feat(chat): /resume and /history open the session history tab (issue #864) (#876)

Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
M57andM57 authored and GitHub committed 2026-08-10 21:43:33 +03:00
1 parent f931565c0d
commit b05cffa9c4
6 files changed
+99 -1

No files matched your search

@@ -446,6 +446,58 @@ class ChatViewModelTest {
}
}
// ── /resume · /history open the history tab (issue #864) ────────────────
@Test
fun slashCommand_resume_requestsHistoryNavigationWithoutGateway() =
runTest {
val (viewModel, sessionId) = createViewModelWithSession()
viewModel.sendMessage("/resume")
advanceUntilIdle()
assertTrue(
"openHistoryRequested must be set for the screen to navigate",
viewModel.uiState.value.openHistoryRequested,
)
// Client-side only: no gateway round-trip for /resume.
verify(exactly = 0) {
HermesWsClient.request(WsMethods.COMMAND_DISPATCH, any(), any())
}
verify(exactly = 0) {
HermesWsClient.request(WsMethods.SLASH_EXEC, any(), any())
}
}
@Test
fun slashCommand_history_requestsHistoryNavigation() =
runTest {
val (viewModel, sessionId) = createViewModelWithSession()
viewModel.sendMessage("/history")
advanceUntilIdle()
assertTrue(viewModel.uiState.value.openHistoryRequested)
verify(exactly = 0) {
HermesWsClient.request(WsMethods.COMMAND_DISPATCH, any(), any())
}
}
@Test
fun consumeOpenHistoryRequest_clearsFlag() =
runTest {
val (viewModel, sessionId) = createViewModelWithSession()
viewModel.sendMessage("/resume")
advanceUntilIdle()
assertTrue(viewModel.uiState.value.openHistoryRequested)
viewModel.consumeOpenHistoryRequest()
advanceUntilIdle()
assertFalse(viewModel.uiState.value.openHistoryRequested)
}
@Test
fun testSlashCommand_unknown_showsErrorMessage() =
runTest {
@@ -63,6 +63,17 @@ class SlashCommandDispatcherTest {
assertEquals(SlashResult.Update, dispatcher.dispatch("/Update"))
}
@Test
fun `resume and history route to OpenHistory`() {
// /resume and /history are CLI-flavored interactive commands the
// mobile gateway path can't answer — handled client-side by opening
// the session history tab (issue #864).
assertEquals(SlashResult.OpenHistory, dispatcher.dispatch("/resume"))
assertEquals(SlashResult.OpenHistory, dispatcher.dispatch("/RESUME"))
assertEquals(SlashResult.OpenHistory, dispatcher.dispatch("/history"))
assertEquals(SlashResult.OpenHistory, dispatcher.dispatch("/History"))
}
@Test
fun `NEW uppercase still routes to NewSession`() {
// Dispatcher lower-cases before matching, so case must not matter.