feat(#441): add profile cloning and description editing (#463)

* feat(#441): add profile cloning and description editing

* feat(#441): add profile builder wizard and API enhancements

Introduce 5-step Profile Builder wizard into ProfilesScreen and add support for create/clone endpoints.

* fix(#441): restore imports and add ProfileInfo constructor defaults

* style: run ktlint format on codebase to fix styling errors

* fix(#441): address PR review comments including provider slug bug, validation, and strings

* fix(#441): remove unused McpServerConfigInput import

---------

Co-authored-by: Hermes Agent <hermes@agent.local>
This commit is contained in:
M57andHermes Agent authored and GitHub committed 2026-07-03 22:24:42 +03:00
1 parent 846a9380e2
commit d181851670
37 files changed
+2299 -448

No files matched your search

@@ -1005,7 +1005,8 @@ class E2eIntegrationTest {
assertEquals(
50.0,
viewModel.uiState.value.stats?.cpu_percent,
viewModel.uiState.value.stats
?.cpu_percent,
)
viewModel.triggerBackup()
@@ -574,16 +574,26 @@ class ConnectViewModelTest {
fun testMultipleProfiles_loadedOnInit() {
val profiles =
listOf(
com.m57.hermescontrol.data.model.ConnectionProfile("a", "Alpha", "10.0.0.1", 9119),
com.m57.hermescontrol.data.model.ConnectionProfile("b", "Beta", "10.0.0.2", 9220),
com.m57.hermescontrol.data.model
.ConnectionProfile("a", "Alpha", "10.0.0.1", 9119),
com.m57.hermescontrol.data.model
.ConnectionProfile("b", "Beta", "10.0.0.2", 9220),
)
every { AuthManager.getConnectionProfiles() } returns profiles
every { AuthManager.getSelectedProfileId() } returns null
val viewModel = ConnectViewModel(mockApp)
assertEquals(2, viewModel.uiState.value.profiles.size)
assertEquals("Alpha", viewModel.uiState.value.profiles[0].name)
assertEquals("Beta", viewModel.uiState.value.profiles[1].name)
assertEquals(
"Alpha",
viewModel.uiState.value.profiles[0]
.name,
)
assertEquals(
"Beta",
viewModel.uiState.value.profiles[1]
.name,
)
}
@Test
@@ -67,7 +67,10 @@ class ModelViewModelTest {
@Test
fun `init with empty pinned models`() {
val viewModel = createViewModel()
assertTrue(viewModel.uiState.value.pinnedModels.isEmpty())
assertTrue(
viewModel.uiState.value.pinnedModels
.isEmpty(),
)
}
@Test
@@ -178,7 +181,10 @@ class ModelViewModelTest {
viewModel.unpinModel("openai", "gpt-4")
testDispatcher.scheduler.advanceUntilIdle()
assertTrue(viewModel.uiState.value.pinnedModels.isEmpty())
assertTrue(
viewModel.uiState.value.pinnedModels
.isEmpty(),
)
// Re-pin same model after unpin
viewModel.pinModel("openai", "gpt-4")