diff --git a/mateclaw-ui/src/components/ChangePasswordDialog.vue b/mateclaw-ui/src/components/ChangePasswordDialog.vue
index 7895e95c..ffc9caa1 100644
--- a/mateclaw-ui/src/components/ChangePasswordDialog.vue
+++ b/mateclaw-ui/src/components/ChangePasswordDialog.vue
@@ -70,7 +70,7 @@
+
+
diff --git a/mateclaw-ui/src/components/skill/ImportHubDialog.vue b/mateclaw-ui/src/components/skill/ImportHubDialog.vue
index 5043a24f..846a2c53 100644
--- a/mateclaw-ui/src/components/skill/ImportHubDialog.vue
+++ b/mateclaw-ui/src/components/skill/ImportHubDialog.vue
@@ -149,7 +149,7 @@
diff --git a/mateclaw-ui/src/views/Backstage.vue b/mateclaw-ui/src/views/Backstage.vue
index 3a7f96a1..78a0662d 100644
--- a/mateclaw-ui/src/views/Backstage.vue
+++ b/mateclaw-ui/src/views/Backstage.vue
@@ -172,7 +172,7 @@
diff --git a/mateclaw-ui/src/views/CronJobs.vue b/mateclaw-ui/src/views/CronJobs.vue
index 7c910dfd..b9b25553 100644
--- a/mateclaw-ui/src/views/CronJobs.vue
+++ b/mateclaw-ui/src/views/CronJobs.vue
@@ -324,7 +324,7 @@
diff --git a/mateclaw-ui/src/views/Memory/components/FactList.vue b/mateclaw-ui/src/views/Memory/components/FactList.vue
index 9570eae7..08b09918 100644
--- a/mateclaw-ui/src/views/Memory/components/FactList.vue
+++ b/mateclaw-ui/src/views/Memory/components/FactList.vue
@@ -71,7 +71,7 @@
diff --git a/mateclaw-ui/src/views/Memory/components/MemoryBrowser.vue b/mateclaw-ui/src/views/Memory/components/MemoryBrowser.vue
index 498e36ce..5e5c7c6b 100644
--- a/mateclaw-ui/src/views/Memory/components/MemoryBrowser.vue
+++ b/mateclaw-ui/src/views/Memory/components/MemoryBrowser.vue
@@ -63,7 +63,7 @@
diff --git a/mateclaw-ui/src/views/Settings/Models/composables/useProviderDiscovery.ts b/mateclaw-ui/src/views/Settings/Models/composables/useProviderDiscovery.ts
index 9490e8cf..695953b2 100644
--- a/mateclaw-ui/src/views/Settings/Models/composables/useProviderDiscovery.ts
+++ b/mateclaw-ui/src/views/Settings/Models/composables/useProviderDiscovery.ts
@@ -1,6 +1,6 @@
import { computed, reactive, ref, type Ref } from 'vue'
import { useI18n } from 'vue-i18n'
-import { ElMessage } from 'element-plus'
+import { mcToast } from '@/composables/useMcToast'
import { modelApi } from '@/api'
import type { DiscoverResult, ProviderInfo, ProviderModelInfo, TestResult } from '@/types'
@@ -98,7 +98,7 @@ export function useProviderDiscovery(deps: ListDeps) {
selectedNewModelIds.value = res.data.newModels.map((m: ProviderModelInfo) => m.id)
}
} catch (error) {
- ElMessage.error(error instanceof Error ? error.message : String(error))
+ mcToast.error(error instanceof Error ? error.message : String(error))
} finally {
discovering.value = false
}
@@ -116,7 +116,7 @@ export function useProviderDiscovery(deps: ListDeps) {
await deps.refreshCurrentProvider(deps.currentProvider.value.id)
return added
} catch (error) {
- ElMessage.error(error instanceof Error ? error.message : String(error))
+ mcToast.error(error instanceof Error ? error.message : String(error))
return 0
} finally {
applyingModels.value = false
diff --git a/mateclaw-ui/src/views/Settings/Models/composables/useProviderEnablement.ts b/mateclaw-ui/src/views/Settings/Models/composables/useProviderEnablement.ts
index 27482ec6..97b7bcc2 100644
--- a/mateclaw-ui/src/views/Settings/Models/composables/useProviderEnablement.ts
+++ b/mateclaw-ui/src/views/Settings/Models/composables/useProviderEnablement.ts
@@ -1,6 +1,6 @@
import { ref, type Ref } from 'vue'
import { useI18n } from 'vue-i18n'
-import { ElMessage } from 'element-plus'
+import { mcToast } from '@/composables/useMcToast'
import { modelApi } from '@/api'
import type { EnableResult, ProviderInfo } from '@/types'
@@ -55,7 +55,7 @@ export function useProviderEnablement(deps: ListDeps) {
await Promise.all([loadCatalog(), deps.loadProviders()])
return res.data as EnableResult
} catch (err) {
- ElMessage.error(err instanceof Error ? err.message : String(err))
+ mcToast.error(err instanceof Error ? err.message : String(err))
return null
} finally {
togglingId.value = null
@@ -72,14 +72,14 @@ export function useProviderEnablement(deps: ListDeps) {
// RFC-074 §2: silent switch + toast. Show the toast here so every caller
// (drawer disable, card more-menu, etc.) gets consistent UX.
if (result?.defaultSwitched) {
- ElMessage.success(t('settings.model.defaultSwitchedToast', {
+ mcToast.success(t('settings.model.defaultSwitchedToast', {
provider: result.newDefaultProviderId,
model: result.newDefaultModel,
}))
}
return result
} catch (err) {
- ElMessage.error(err instanceof Error ? err.message : String(err))
+ mcToast.error(err instanceof Error ? err.message : String(err))
return null
} finally {
togglingId.value = null
diff --git a/mateclaw-ui/src/views/Settings/Models/composables/useProviderForm.ts b/mateclaw-ui/src/views/Settings/Models/composables/useProviderForm.ts
index 5e50c050..3a9e9780 100644
--- a/mateclaw-ui/src/views/Settings/Models/composables/useProviderForm.ts
+++ b/mateclaw-ui/src/views/Settings/Models/composables/useProviderForm.ts
@@ -1,6 +1,6 @@
import { computed, reactive, ref } from 'vue'
import { useI18n } from 'vue-i18n'
-import { ElMessage } from 'element-plus'
+import { mcToast } from '@/composables/useMcToast'
import { mcConfirm } from '@/components/common/useConfirm'
import { modelApi } from '@/api'
import type { ProviderInfo } from '@/types'
@@ -159,7 +159,7 @@ export function useProviderForm(deps: ListDeps) {
if (!editingProvider.value) {
const id = providerForm.id.trim()
if (!id || !PROVIDER_ID_PATTERN.test(id)) {
- ElMessage.error(t('settings.model.providerIdInvalid'))
+ mcToast.error(t('settings.model.providerIdInvalid'))
return false
}
providerForm.id = id
diff --git a/mateclaw-ui/src/views/Settings/Models/composables/useProviderOAuth.ts b/mateclaw-ui/src/views/Settings/Models/composables/useProviderOAuth.ts
index 99244cc4..f6f6c9ff 100644
--- a/mateclaw-ui/src/views/Settings/Models/composables/useProviderOAuth.ts
+++ b/mateclaw-ui/src/views/Settings/Models/composables/useProviderOAuth.ts
@@ -1,6 +1,6 @@
import { ref, type Ref } from 'vue'
import { useI18n } from 'vue-i18n'
-import { ElMessage } from 'element-plus'
+import { mcToast } from '@/composables/useMcToast'
import { claudeCodeOAuthApi, oauthApi } from '@/api'
import type { ProviderInfo } from '@/types'
@@ -74,12 +74,12 @@ export function useProviderOAuth(deps: FormDeps & ListDeps) {
try {
start = await oauthApi.deviceStart()
} catch (e: any) {
- ElMessage.error(e.msg || 'Device code request failed')
+ mcToast.error(e.msg || 'Device code request failed')
return
}
const data = start.data
if (!data?.deviceAuthId || !data?.userCode) {
- ElMessage.error('Device code response was incomplete')
+ mcToast.error('Device code response was incomplete')
return
}
@@ -100,7 +100,7 @@ export function useProviderOAuth(deps: FormDeps & ListDeps) {
return
}
if (Date.now() > deviceCodeDialog.value.expiresAt) {
- ElMessage.warning(t('settings.model.oauthDeviceExpired'))
+ mcToast.warning(t('settings.model.oauthDeviceExpired'))
closeDeviceCodeDialog()
return
}
@@ -111,12 +111,12 @@ export function useProviderOAuth(deps: FormDeps & ListDeps) {
activeDeviceAuthId = null
stopDevicePolling()
deviceCodeDialog.value.visible = false
- ElMessage.success(t('settings.model.oauthLoginSuccess'))
+ mcToast.success(t('settings.model.oauthLoginSuccess'))
await reloadProvidersAndSync()
return
}
if (status === 'EXPIRED') {
- ElMessage.warning(t('settings.model.oauthDeviceExpired'))
+ mcToast.warning(t('settings.model.oauthDeviceExpired'))
closeDeviceCodeDialog()
return
}
@@ -131,13 +131,13 @@ export function useProviderOAuth(deps: FormDeps & ListDeps) {
try {
const res: any = await claudeCodeOAuthApi.reload()
if (res.data?.connected && !res.data?.expired) {
- ElMessage.success(t('settings.model.oauthLoginSuccess'))
+ mcToast.success(t('settings.model.oauthLoginSuccess'))
} else {
- ElMessage.warning(t('settings.model.claudeCodeOauthInstructions'))
+ mcToast.warning(t('settings.model.claudeCodeOauthInstructions'))
}
await reloadProvidersAndSync()
} catch (e: any) {
- ElMessage.error(e.msg || 'Claude Code OAuth detection failed')
+ mcToast.error(e.msg || 'Claude Code OAuth detection failed')
}
return
}
@@ -160,14 +160,14 @@ export function useProviderOAuth(deps: FormDeps & ListDeps) {
if (statusRes.data?.connected) {
clearInterval(pollInterval)
if (authWindow && !authWindow.closed) authWindow.close()
- ElMessage.success(t('settings.model.oauthLoginSuccess'))
+ mcToast.success(t('settings.model.oauthLoginSuccess'))
await reloadProvidersAndSync()
}
} catch { /* ignore polling errors */ }
}, 2000)
setTimeout(() => clearInterval(pollInterval), 30000)
} catch (e: any) {
- ElMessage.error(e.msg || 'OAuth login failed')
+ mcToast.error(e.msg || 'OAuth login failed')
}
}
@@ -176,15 +176,15 @@ export function useProviderOAuth(deps: FormDeps & ListDeps) {
// Code app, not MateClaw — direct the user to log out there instead of
// clobbering their machine-level login.
if (providerId === 'anthropic-claude-code') {
- ElMessage.info(t('settings.model.claudeCodeOauthRevokeHint'))
+ mcToast.info(t('settings.model.claudeCodeOauthRevokeHint'))
return
}
try {
await oauthApi.revoke()
- ElMessage.success(t('settings.model.oauthRevokeSuccess'))
+ mcToast.success(t('settings.model.oauthRevokeSuccess'))
await reloadProvidersAndSync()
} catch (e: any) {
- ElMessage.error(e.msg || 'OAuth revoke failed')
+ mcToast.error(e.msg || 'OAuth revoke failed')
}
}
diff --git a/mateclaw-ui/src/views/Settings/Models/composables/useProviderPool.ts b/mateclaw-ui/src/views/Settings/Models/composables/useProviderPool.ts
index f8d05004..2fd3ad1b 100644
--- a/mateclaw-ui/src/views/Settings/Models/composables/useProviderPool.ts
+++ b/mateclaw-ui/src/views/Settings/Models/composables/useProviderPool.ts
@@ -1,6 +1,6 @@
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
-import { ElMessage } from 'element-plus'
+import { mcToast } from '@/composables/useMcToast'
import { providerPoolApi } from '@/api'
import type { ProviderInfo } from '@/types'
@@ -29,13 +29,13 @@ export function useProviderPool(deps: ListDeps) {
// refreshes everything the UI needs (badge + status pill + dropdown filter).
await deps.loadProviders()
if (data.success) {
- ElMessage.success(t('settings.model.poolReprobeOk'))
+ mcToast.success(t('settings.model.poolReprobeOk'))
} else {
- ElMessage.warning(t('settings.model.poolReprobeFail', { error: data.errorMessage || '—' }))
+ mcToast.warning(t('settings.model.poolReprobeFail', { error: data.errorMessage || '—' }))
}
return data
} catch (err) {
- ElMessage.error(t('settings.model.poolReprobeFail', {
+ mcToast.error(t('settings.model.poolReprobeFail', {
error: err instanceof Error ? err.message : String(err)
}))
} finally {
diff --git a/mateclaw-ui/src/views/Settings/Models/index.vue b/mateclaw-ui/src/views/Settings/Models/index.vue
index c16bc397..967610ce 100644
--- a/mateclaw-ui/src/views/Settings/Models/index.vue
+++ b/mateclaw-ui/src/views/Settings/Models/index.vue
@@ -191,7 +191,7 @@
diff --git a/mateclaw-ui/src/views/SkillMarket.vue b/mateclaw-ui/src/views/SkillMarket.vue
index d64ae729..078c10d9 100644
--- a/mateclaw-ui/src/views/SkillMarket.vue
+++ b/mateclaw-ui/src/views/SkillMarket.vue
@@ -654,7 +654,7 @@
diff --git a/mateclaw-ui/src/views/Triggers.vue b/mateclaw-ui/src/views/Triggers.vue
index cb4cca56..c7f6d863 100644
--- a/mateclaw-ui/src/views/Triggers.vue
+++ b/mateclaw-ui/src/views/Triggers.vue
@@ -171,7 +171,7 @@