system notification like kilocode

This commit is contained in:
NaccOll 2025-08-12 14:28:54 +08:00
parent 0c481a3cf9
commit cc8e3ef511
29 changed files with 462 additions and 2 deletions

View file

@ -97,6 +97,7 @@ export const globalSettingsSchema = z.object({
ttsSpeed: z.number().optional(),
soundEnabled: z.boolean().optional(),
soundVolume: z.number().optional(),
systemNotificationsEnabled: z.boolean().optional(),
maxOpenTabsContext: z.number().optional(),
maxWorkspaceFiles: z.number().optional(),
@ -261,6 +262,7 @@ export const EVALS_SETTINGS: RooCodeSettings = {
ttsSpeed: 1,
soundEnabled: false,
soundVolume: 0.5,
systemNotificationsEnabled: false,
terminalOutputLineLimit: 500,
terminalOutputCharacterLimit: DEFAULT_TERMINAL_OUTPUT_CHARACTER_LIMIT,

View file

@ -1698,6 +1698,7 @@ export class ClineProvider
soundEnabled,
ttsEnabled,
ttsSpeed,
systemNotificationsEnabled,
diffEnabled,
enableCheckpoints,
taskHistory,
@ -1804,6 +1805,7 @@ export class ClineProvider
soundEnabled: soundEnabled ?? false,
ttsEnabled: ttsEnabled ?? false,
ttsSpeed: ttsSpeed ?? 1.0,
systemNotificationsEnabled: systemNotificationsEnabled ?? false,
diffEnabled: diffEnabled ?? true,
enableCheckpoints: enableCheckpoints ?? true,
shouldShowAnnouncement:
@ -1999,6 +2001,7 @@ export class ClineProvider
soundEnabled: stateValues.soundEnabled ?? false,
ttsEnabled: stateValues.ttsEnabled ?? false,
ttsSpeed: stateValues.ttsSpeed ?? 1.0,
systemNotificationsEnabled: stateValues.systemNotificationsEnabled ?? false,
diffEnabled: stateValues.diffEnabled ?? true,
enableCheckpoints: stateValues.enableCheckpoints ?? true,
soundVolume: stateValues.soundVolume,

View file

@ -29,6 +29,7 @@ import { checkExistKey } from "../../shared/checkExistApiConfig"
import { experimentDefault } from "../../shared/experiments"
import { Terminal } from "../../integrations/terminal/Terminal"
import { openFile } from "../../integrations/misc/open-file"
import { showSystemNotification } from "../../integrations/notifications"
import { CodeIndexManager } from "../../services/code-index/manager"
import { openImage, saveImage } from "../../integrations/misc/image-handler"
import { selectImages } from "../../integrations/misc/process-images"
@ -975,6 +976,20 @@ export const webviewMessageHandler = async (
await updateGlobalState("soundVolume", soundVolume)
await provider.postStateToWebview()
break
case "showSystemNotification":
const isSystemNotificationsEnabled = getGlobalState("systemNotificationsEnabled") ?? false
if (!isSystemNotificationsEnabled) {
break
}
if (message.notificationOptions) {
showSystemNotification(message.notificationOptions)
}
break
case "systemNotificationsEnabled":
const systemNotificationsEnabled = message.bool ?? true
await updateGlobalState("systemNotificationsEnabled", systemNotificationsEnabled)
await provider.postStateToWebview()
break
case "ttsEnabled":
const ttsEnabled = message.bool ?? true
await updateGlobalState("ttsEnabled", ttsEnabled)

View file

@ -0,0 +1,97 @@
import { execa } from "execa"
import { platform } from "os"
interface NotificationOptions {
title?: string
subtitle?: string
message: string
}
async function showMacOSNotification(options: NotificationOptions): Promise<void> {
const { title, subtitle = "", message } = options
const script = `display notification "${message}" with title "${title}" subtitle "${subtitle}" sound name "Tink"`
try {
await execa("osascript", ["-e", script])
} catch (error) {
throw new Error(`Failed to show macOS notification: ${error}`)
}
}
async function showWindowsNotification(options: NotificationOptions): Promise<void> {
const { subtitle, message } = options
const script = `
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | Out-Null
$template = @"
<toast>
<visual>
<binding template="ToastText02">
<text id="1">${subtitle}</text>
<text id="2">${message}</text>
</binding>
</visual>
</toast>
"@
$xml = New-Object Windows.Data.Xml.Dom.XmlDocument
$xml.LoadXml($template)
$toast = [Windows.UI.Notifications.ToastNotification]::new($xml)
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("Roo Code").Show($toast)
`
try {
await execa("powershell", ["-Command", script])
} catch (error) {
throw new Error(`Failed to show Windows notification: ${error}`)
}
}
async function showLinuxNotification(options: NotificationOptions): Promise<void> {
const { title = "", subtitle = "", message } = options
// Combine subtitle and message if subtitle exists
const fullMessage = subtitle ? `${subtitle}\n${message}` : message
try {
await execa("notify-send", [title, fullMessage])
} catch (error) {
throw new Error(`Failed to show Linux notification: ${error}`)
}
}
export async function showSystemNotification(options: NotificationOptions): Promise<void> {
try {
const { title = "Roo Code", message } = options
if (!message) {
throw new Error("Message is required")
}
const escapedOptions = {
...options,
title: title.replace(/"/g, '\\"'),
message: message.replace(/"/g, '\\"'),
subtitle: options.subtitle?.replace(/"/g, '\\"') || "",
}
switch (platform()) {
case "darwin":
await showMacOSNotification(escapedOptions)
break
case "win32":
await showWindowsNotification(escapedOptions)
break
case "linux":
await showLinuxNotification(escapedOptions)
break
default:
throw new Error("Unsupported platform")
}
} catch (error) {
console.error("Could not show system notification", error)
}
}

View file

@ -96,6 +96,7 @@ export interface ExtensionMessage {
| "remoteBrowserEnabled"
| "ttsStart"
| "ttsStop"
| "showSystemNotification"
| "maxReadFileLine"
| "fileSearchResults"
| "toggleApiConfigPin"
@ -233,6 +234,7 @@ export type ExtensionState = Pick<
| "ttsSpeed"
| "soundEnabled"
| "soundVolume"
| "systemNotificationsEnabled"
// | "maxOpenTabsContext" // Optional in GlobalSettings, required here.
// | "maxWorkspaceFiles" // Optional in GlobalSettings, required here.
// | "showRooIgnoredFiles" // Optional in GlobalSettings, required here.

View file

@ -94,6 +94,8 @@ export interface WebviewMessage {
| "ttsEnabled"
| "ttsSpeed"
| "soundVolume"
| "showSystemNotification"
| "systemNotificationsEnabled"
| "diffEnabled"
| "enableCheckpoints"
| "browserViewportSize"
@ -274,6 +276,11 @@ export interface WebviewMessage {
codebaseIndexGeminiApiKey?: string
codebaseIndexMistralApiKey?: string
}
notificationOptions?: {
title?: string
subtitle?: string
message: string
}
}
export const checkoutDiffPayloadSchema = z.object({

View file

@ -57,6 +57,7 @@ import { CheckpointWarning } from "./CheckpointWarning"
import QueuedMessages from "./QueuedMessages"
import { getLatestTodo } from "@roo/todo"
import { QueuedMessage } from "@roo-code/types"
import { showSystemNotification } from "@/utils/showSystemNotification"
export interface ChatViewProps {
isHidden: boolean
@ -276,6 +277,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
switch (lastMessage.ask) {
case "api_req_failed":
playSound("progress_loop")
showSystemNotification(t("settings:notifications.system.apiReqFailed"))
setSendingDisabled(true)
setClineAsk("api_req_failed")
setEnableButtons(true)
@ -284,6 +286,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
break
case "mistake_limit_reached":
playSound("progress_loop")
showSystemNotification(t("settings:notifications.system.mistakeLimitReached"))
setSendingDisabled(false)
setClineAsk("mistake_limit_reached")
setEnableButtons(true)
@ -293,6 +296,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
case "followup":
if (!isPartial) {
playSound("notification")
showSystemNotification(t("settings:notifications.system.followup"))
}
setSendingDisabled(isPartial)
setClineAsk("followup")
@ -307,6 +311,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
case "tool":
if (!isAutoApproved(lastMessage) && !isPartial) {
playSound("notification")
showSystemNotification(t("settings:notifications.system.toolRequest"))
}
setSendingDisabled(isPartial)
setClineAsk("tool")
@ -342,6 +347,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
case "browser_action_launch":
if (!isAutoApproved(lastMessage) && !isPartial) {
playSound("notification")
showSystemNotification(t("settings:notifications.system.browserAction"))
}
setSendingDisabled(isPartial)
setClineAsk("browser_action_launch")
@ -352,6 +358,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
case "command":
if (!isAutoApproved(lastMessage) && !isPartial) {
playSound("notification")
showSystemNotification(t("settings:notifications.system.command"))
}
setSendingDisabled(isPartial)
setClineAsk("command")
@ -369,6 +376,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
case "use_mcp_server":
if (!isAutoApproved(lastMessage) && !isPartial) {
playSound("notification")
showSystemNotification(t("settings:notifications.system.useMcpServer"))
}
setSendingDisabled(isPartial)
setClineAsk("use_mcp_server")
@ -380,6 +388,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
// extension waiting for feedback. but we can just present a new task button
if (!isPartial) {
playSound("celebration")
showSystemNotification(t("settings:notifications.system.completionResult"))
}
setSendingDisabled(isPartial)
setClineAsk("completion_result")

View file

@ -1,19 +1,24 @@
import { HTMLAttributes } from "react"
import { useAppTranslation } from "@/i18n/TranslationContext"
import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"
import { VSCodeCheckbox, VSCodeButton } from "@vscode/webview-ui-toolkit/react"
import { Bell } from "lucide-react"
import { SetCachedStateField } from "./types"
import { SectionHeader } from "./SectionHeader"
import { Section } from "./Section"
import { Slider } from "../ui"
import { vscode } from "../../utils/vscode"
type NotificationSettingsProps = HTMLAttributes<HTMLDivElement> & {
ttsEnabled?: boolean
ttsSpeed?: number
soundEnabled?: boolean
soundVolume?: number
setCachedStateField: SetCachedStateField<"ttsEnabled" | "ttsSpeed" | "soundEnabled" | "soundVolume">
systemNotificationsEnabled?: boolean
setCachedStateField: SetCachedStateField<
"ttsEnabled" | "ttsSpeed" | "soundEnabled" | "soundVolume" | "systemNotificationsEnabled"
>
isChangeDetected: boolean
}
export const NotificationSettings = ({
@ -21,10 +26,22 @@ export const NotificationSettings = ({
ttsSpeed,
soundEnabled,
soundVolume,
systemNotificationsEnabled,
isChangeDetected,
setCachedStateField,
...props
}: NotificationSettingsProps) => {
const { t } = useAppTranslation()
const onTestNotificationClick = () => {
vscode.postMessage({
type: "showSystemNotification",
notificationOptions: {
title: t("settings.notifications.system.testTitle"),
message: t("settings.notifications.system.testMessage"),
},
})
}
return (
<div {...props}>
<SectionHeader>
@ -35,6 +52,26 @@ export const NotificationSettings = ({
</SectionHeader>
<Section>
<div>
<VSCodeCheckbox
checked={systemNotificationsEnabled}
onChange={(e: any) => setCachedStateField("systemNotificationsEnabled", e.target.checked)}
data-testid="system-notifications-enabled-checkbox">
<span className="font-medium">{t("settings:notifications.system.label")}</span>
</VSCodeCheckbox>
<div className="text-vscode-descriptionForeground text-sm mt-1 mb-2">
{t("settings:notifications.system.description")}
</div>
{systemNotificationsEnabled && !isChangeDetected && (
<VSCodeButton
appearance="secondary"
onClick={onTestNotificationClick}
data-testid="test-system-notification-button">
{t("settings:notifications.system.testButton")}
</VSCodeButton>
)}
</div>
<div>
<VSCodeCheckbox
checked={ttsEnabled}

View file

@ -154,6 +154,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
ttsEnabled,
ttsSpeed,
soundVolume,
systemNotificationsEnabled,
telemetrySetting,
terminalOutputLineLimit,
terminalOutputCharacterLimit,
@ -300,6 +301,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
vscode.postMessage({ type: "ttsEnabled", bool: ttsEnabled })
vscode.postMessage({ type: "ttsSpeed", value: ttsSpeed })
vscode.postMessage({ type: "soundVolume", value: soundVolume })
vscode.postMessage({ type: "systemNotificationsEnabled", bool: systemNotificationsEnabled })
vscode.postMessage({ type: "diffEnabled", bool: diffEnabled })
vscode.postMessage({ type: "enableCheckpoints", bool: enableCheckpoints })
vscode.postMessage({ type: "browserViewportSize", text: browserViewportSize })
@ -663,7 +665,9 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
ttsSpeed={ttsSpeed}
soundEnabled={soundEnabled}
soundVolume={soundVolume}
systemNotificationsEnabled={systemNotificationsEnabled}
setCachedStateField={setCachedStateField}
isChangeDetected={isChangeDetected}
/>
)}

View file

@ -84,6 +84,7 @@ export interface ExtensionStateContextType extends ExtensionState {
setTerminalZdotdir: (value: boolean) => void
setTtsEnabled: (value: boolean) => void
setTtsSpeed: (value: number) => void
setSystemNotificationsEnabled: (value: boolean) => void
setDiffEnabled: (value: boolean) => void
setEnableCheckpoints: (value: boolean) => void
setBrowserViewportSize: (value: string) => void
@ -441,6 +442,8 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
setSoundVolume: (value) => setState((prevState) => ({ ...prevState, soundVolume: value })),
setTtsEnabled: (value) => setState((prevState) => ({ ...prevState, ttsEnabled: value })),
setTtsSpeed: (value) => setState((prevState) => ({ ...prevState, ttsSpeed: value })),
setSystemNotificationsEnabled: (value) =>
setState((prevState) => ({ ...prevState, systemNotificationsEnabled: value })),
setDiffEnabled: (value) => setState((prevState) => ({ ...prevState, diffEnabled: value })),
setEnableCheckpoints: (value) => setState((prevState) => ({ ...prevState, enableCheckpoints: value })),
setBrowserViewportSize: (value: string) =>

View file

@ -509,6 +509,21 @@
"label": "Habilitar text a veu",
"description": "Quan està habilitat, Roo llegirà en veu alta les seves respostes utilitzant text a veu.",
"speedLabel": "Velocitat"
},
"system": {
"label": "Habilitar notificacions del sistema",
"description": "Quan està habilitat, Roo mostrarà notificacions del sistema per a esdeveniments i missatges importants.",
"testButton": "Provar notificació del sistema",
"testTitle": "Roo Code",
"testMessage": "Les notificacions del sistema funcionen correctament!",
"apiReqFailed": "Error de sol·licitud d'API",
"mistakeLimitReached": "Límit d'errors assolit",
"followup": "Esperant la teva resposta de seguiment",
"toolRequest": "Sol·licitud d'eina esperant aprovació",
"browserAction": "Acció del navegador esperant aprovació",
"command": "Ordre esperant aprovació",
"useMcpServer": "Utilitzar servidor MCP per a l'aprovació",
"completionResult": "Tasca completada"
}
},
"contextManagement": {

View file

@ -509,6 +509,21 @@
"label": "Text-zu-Sprache aktivieren",
"description": "Wenn aktiviert, liest Roo seine Antworten mit Text-zu-Sprache laut vor.",
"speedLabel": "Geschwindigkeit"
},
"system": {
"label": "Systembenachrichtigungen aktivieren",
"description": "Wenn aktiviert, zeigt Roo Systembenachrichtigungen für wichtige Ereignisse und Nachrichten an.",
"testButton": "Systembenachrichtigung testen",
"testTitle": "Roo Code",
"testMessage": "Systembenachrichtigungen funktionieren ordnungsgemäß!",
"apiReqFailed": "API-Anfragefehler",
"mistakeLimitReached": "Fehlerlimit erreicht",
"followup": "Warte auf deine Antwort",
"toolRequest": "Tool-Anfrage wartet auf Genehmigung",
"browserAction": "Browser-Aktion wartet auf Genehmigung",
"command": "Befehl wartet auf Genehmigung",
"useMcpServer": "MCP-Server für Genehmigung verwenden",
"completionResult": "Aufgabe abgeschlossen"
}
},
"contextManagement": {

View file

@ -508,6 +508,21 @@
"label": "Enable text-to-speech",
"description": "When enabled, Roo will read aloud its responses using text-to-speech.",
"speedLabel": "Speed"
},
"system": {
"label": "Enable system notifications",
"description": "When enabled, Roo will show system notifications for important events and messages.",
"testButton": "Test System Notification",
"testTitle": "Roo Code",
"testMessage": "System notifications are working properly!",
"apiReqFailed": "API request error",
"mistakeLimitReached": "Mistake limit reached",
"followup": "Waiting for your follow-up reply",
"toolRequest": "Tool request waiting for approval",
"browserAction": "Browser action waiting for approval",
"command": "Command waiting for approval",
"useMcpServer": "Use MCP server for approval",
"completionResult": "Task Complete"
}
},
"contextManagement": {

View file

@ -509,6 +509,21 @@
"label": "Habilitar texto a voz",
"description": "Cuando está habilitado, Roo leerá en voz alta sus respuestas usando texto a voz.",
"speedLabel": "Velocidad"
},
"system": {
"label": "Habilitar notificaciones del sistema",
"description": "Cuando está habilitado, Roo mostrará notificaciones del sistema para eventos y mensajes importantes.",
"testButton": "Probar notificación del sistema",
"testTitle": "Roo Code",
"testMessage": "¡Las notificaciones del sistema funcionan correctamente!",
"apiReqFailed": "Error de solicitud de API",
"mistakeLimitReached": "Límite de errores alcanzado",
"followup": "Esperando tu respuesta de seguimiento",
"toolRequest": "Solicitud de herramienta esperando aprobación",
"browserAction": "Acción del navegador esperando aprobación",
"command": "Comando esperando aprobación",
"useMcpServer": "Usar servidor MCP para aprobación",
"completionResult": "Tarea completada"
}
},
"contextManagement": {

View file

@ -509,6 +509,21 @@
"label": "Activer la synthèse vocale",
"description": "Lorsque cette option est activée, Roo lira ses réponses à haute voix en utilisant la synthèse vocale.",
"speedLabel": "Vitesse"
},
"system": {
"label": "Activer les notifications système",
"description": "Lorsque cette option est activée, Roo affichera des notifications système pour les événements et messages importants.",
"testButton": "Tester la notification système",
"testTitle": "Roo Code",
"testMessage": "Les notifications système fonctionnent correctement !",
"apiReqFailed": "Erreur de requête API",
"mistakeLimitReached": "Limite d'erreurs atteinte",
"followup": "En attente de ta réponse de suivi",
"toolRequest": "Demande d'outil en attente d'approbation",
"browserAction": "Action du navigateur en attente d'approbation",
"command": "Commande en attente d'approbation",
"useMcpServer": "Utiliser le serveur MCP pour l'approbation",
"completionResult": "Tâche terminée"
}
},
"contextManagement": {

View file

@ -509,6 +509,21 @@
"label": "टेक्स्ट-टू-स्पीच सक्षम करें",
"description": "जब सक्षम होता है, तो Roo टेक्स्ट-टू-स्पीच का उपयोग करके अपनी प्रतिक्रियाओं को बोलकर पढ़ेगा।",
"speedLabel": "गति"
},
"system": {
"label": "सिस्टम सूचनाएं सक्षम करें",
"description": "जब सक्षम होता है, तो Roo महत्वपूर्ण घटनाओं और संदेशों के लिए सिस्टम सूचनाएं दिखाएगा।",
"testButton": "सिस्टम सूचना परीक्षण करें",
"testTitle": "Roo Code",
"testMessage": "सिस्टम सूचनाएं ठीक से काम कर रही हैं!",
"apiReqFailed": "API अनुरोध त्रुटि",
"mistakeLimitReached": "त्रुटि सीमा पहुंच गई",
"followup": "आपके फॉलो-अप उत्तर की प्रतीक्षा कर रहे हैं",
"toolRequest": "टूल अनुरोध अनुमोदन की प्रतीक्षा में",
"browserAction": "ब्राउज़र कार्य अनुमोदन की प्रतीक्षा में",
"command": "कमांड अनुमोदन की प्रतीक्षा में",
"useMcpServer": "अनुमोदन के लिए MCP सर्वर का उपयोग करें",
"completionResult": "कार्य पूर्ण"
}
},
"contextManagement": {

View file

@ -513,6 +513,21 @@
"label": "Aktifkan text-to-speech",
"description": "Ketika diaktifkan, Roo akan membacakan responnya menggunakan text-to-speech.",
"speedLabel": "Kecepatan"
},
"system": {
"label": "Aktifkan notifikasi sistem",
"description": "Ketika diaktifkan, Roo akan menampilkan notifikasi sistem untuk event dan pesan penting.",
"testButton": "Tes notifikasi sistem",
"testTitle": "Roo Code",
"testMessage": "Notifikasi sistem berfungsi dengan baik!",
"apiReqFailed": "Kesalahan permintaan API",
"mistakeLimitReached": "Batas kesalahan tercapai",
"followup": "Menunggu balasan lanjutan Anda",
"toolRequest": "Permintaan tool menunggu persetujuan",
"browserAction": "Aksi browser menunggu persetujuan",
"command": "Perintah menunggu persetujuan",
"useMcpServer": "Gunakan server MCP untuk persetujuan",
"completionResult": "Tugas selesai"
}
},
"contextManagement": {

View file

@ -509,6 +509,21 @@
"label": "Abilita sintesi vocale",
"description": "Quando abilitato, Roo leggerà ad alta voce le sue risposte utilizzando la sintesi vocale.",
"speedLabel": "Velocità"
},
"system": {
"label": "Abilita notifiche di sistema",
"description": "Quando abilitato, Roo mostrerà notifiche di sistema per eventi e messaggi importanti.",
"testButton": "Testa notifica di sistema",
"testTitle": "Roo Code",
"testMessage": "Le notifiche di sistema funzionano correttamente!",
"apiReqFailed": "Errore richiesta API",
"mistakeLimitReached": "Limite errori raggiunto",
"followup": "In attesa della tua risposta di follow-up",
"toolRequest": "Richiesta strumento in attesa di approvazione",
"browserAction": "Azione del browser in attesa di approvazione",
"command": "Comando in attesa di approvazione",
"useMcpServer": "Usa server MCP per approvazione",
"completionResult": "Attività completata"
}
},
"contextManagement": {

View file

@ -509,6 +509,21 @@
"label": "音声合成を有効化",
"description": "有効にすると、Rooは音声合成を使用して応答を音声で読み上げます。",
"speedLabel": "速度"
},
"system": {
"label": "システム通知を有効化",
"description": "有効にすると、Rooは重要なイベントやメッセージのためにシステム通知を表示します。",
"testButton": "システム通知をテスト",
"testTitle": "Roo Code",
"testMessage": "システム通知が正常に動作しています!",
"apiReqFailed": "APIリクエストエラー",
"mistakeLimitReached": "エラー制限に達しました",
"followup": "フォローアップの返信をお待ちしています",
"toolRequest": "ツールリクエストが承認待ちです",
"browserAction": "ブラウザアクションが承認待ちです",
"command": "コマンドが承認待ちです",
"useMcpServer": "承認にMCPサーバーを使用",
"completionResult": "タスク完了"
}
},
"contextManagement": {

View file

@ -509,6 +509,21 @@
"label": "음성 합성 활성화",
"description": "활성화되면 Roo는 음성 합성을 사용하여 응답을 소리내어 읽습니다.",
"speedLabel": "속도"
},
"system": {
"label": "시스템 알림 활성화",
"description": "활성화되면 Roo는 중요한 이벤트와 메시지에 대한 시스템 알림을 표시합니다.",
"testButton": "시스템 알림 테스트",
"testTitle": "Roo Code",
"testMessage": "시스템 알림이 정상적으로 작동합니다!",
"apiReqFailed": "API 요청 오류",
"mistakeLimitReached": "오류 한도 도달",
"followup": "후속 답변을 기다리고 있습니다",
"toolRequest": "도구 요청이 승인 대기 중입니다",
"browserAction": "브라우저 작업이 승인 대기 중입니다",
"command": "명령이 승인 대기 중입니다",
"useMcpServer": "승인에 MCP 서버 사용",
"completionResult": "작업 완료"
}
},
"contextManagement": {

View file

@ -509,6 +509,21 @@
"label": "Tekst-naar-spraak inschakelen",
"description": "Indien ingeschakeld, leest Roo zijn antwoorden hardop voor via tekst-naar-spraak.",
"speedLabel": "Snelheid"
},
"system": {
"label": "Systeemmeldingen inschakelen",
"description": "Indien ingeschakeld, toont Roo systeemmeldingen voor belangrijke gebeurtenissen en berichten.",
"testButton": "Systeemmelding testen",
"testTitle": "Roo Code",
"testMessage": "Systeemmeldingen werken correct!",
"apiReqFailed": "API-verzoekfout",
"mistakeLimitReached": "Foutlimiet bereikt",
"followup": "Wachten op je vervolgantwoord",
"toolRequest": "Toolverzoek wacht op goedkeuring",
"browserAction": "Browseractie wacht op goedkeuring",
"command": "Opdracht wacht op goedkeuring",
"useMcpServer": "MCP-server gebruiken voor goedkeuring",
"completionResult": "Taak voltooid"
}
},
"contextManagement": {

View file

@ -509,6 +509,21 @@
"label": "Włącz syntezę mowy",
"description": "Gdy włączone, Roo będzie czytać na głos swoje odpowiedzi za pomocą syntezy mowy.",
"speedLabel": "Szybkość"
},
"system": {
"label": "Włącz powiadomienia systemowe",
"description": "Gdy włączone, Roo będzie wyświetlać powiadomienia systemowe dla ważnych zdarzeń i wiadomości.",
"testButton": "Testuj powiadomienie systemowe",
"testTitle": "Roo Code",
"testMessage": "Powiadomienia systemowe działają prawidłowo!",
"apiReqFailed": "Błąd żądania API",
"mistakeLimitReached": "Osiągnięto limit błędów",
"followup": "Oczekiwanie na twoją odpowiedź",
"toolRequest": "Żądanie narzędzia oczekuje na zatwierdzenie",
"browserAction": "Akcja przeglądarki oczekuje na zatwierdzenie",
"command": "Polecenie oczekuje na zatwierdzenie",
"useMcpServer": "Użyj serwera MCP do zatwierdzenia",
"completionResult": "Zadanie ukończone"
}
},
"contextManagement": {

View file

@ -509,6 +509,21 @@
"label": "Ativar texto para fala",
"description": "Quando ativado, o Roo lerá em voz alta suas respostas usando texto para fala.",
"speedLabel": "Velocidade"
},
"system": {
"label": "Ativar notificações do sistema",
"description": "Quando ativado, o Roo mostrará notificações do sistema para eventos e mensagens importantes.",
"testButton": "Testar notificação do sistema",
"testTitle": "Roo Code",
"testMessage": "As notificações do sistema estão funcionando corretamente!",
"apiReqFailed": "Erro de solicitação da API",
"mistakeLimitReached": "Limite de erros alcançado",
"followup": "Aguardando sua resposta de acompanhamento",
"toolRequest": "Solicitação de ferramenta aguardando aprovação",
"browserAction": "Ação do navegador aguardando aprovação",
"command": "Comando aguardando aprovação",
"useMcpServer": "Usar servidor MCP para aprovação",
"completionResult": "Tarefa concluída"
}
},
"contextManagement": {

View file

@ -509,6 +509,21 @@
"label": "Включить озвучивание",
"description": "Если включено, Roo будет озвучивать свои ответы с помощью преобразования текста в речь.",
"speedLabel": "Скорость"
},
"system": {
"label": "Включить системные уведомления",
"description": "Если включено, Roo будет показывать системные уведомления для важных событий и сообщений.",
"testButton": "Тестировать системное уведомление",
"testTitle": "Roo Code",
"testMessage": "Системные уведомления работают правильно!",
"apiReqFailed": "Ошибка API-запроса",
"mistakeLimitReached": "Достигнут лимит ошибок",
"followup": "Ожидаем твой ответ",
"toolRequest": "Запрос инструмента ожидает одобрения",
"browserAction": "Действие браузера ожидает одобрения",
"command": "Команда ожидает одобрения",
"useMcpServer": "Использовать MCP-сервер для одобрения",
"completionResult": "Задача завершена"
}
},
"contextManagement": {

View file

@ -509,6 +509,21 @@
"label": "Metinden sese özelliğini etkinleştir",
"description": "Etkinleştirildiğinde, Roo yanıtlarını metinden sese teknolojisi kullanarak sesli okuyacaktır.",
"speedLabel": "Hız"
},
"system": {
"label": "Sistem bildirimlerini etkinleştir",
"description": "Etkinleştirildiğinde, Roo önemli olaylar ve mesajlar için sistem bildirimleri gösterecektir.",
"testButton": "Sistem bildirimini test et",
"testTitle": "Roo Code",
"testMessage": "Sistem bildirimleri düzgün çalışıyor!",
"apiReqFailed": "API istek hatası",
"mistakeLimitReached": "Hata sınırına ulaşıldı",
"followup": "Takip yanıtını bekliyoruz",
"toolRequest": "Araç isteği onay bekliyor",
"browserAction": "Tarayıcı eylemi onay bekliyor",
"command": "Komut onay bekliyor",
"useMcpServer": "Onay için MCP sunucusu kullan",
"completionResult": "Görev tamamlandı"
}
},
"contextManagement": {

View file

@ -509,6 +509,21 @@
"label": "Bật chuyển văn bản thành giọng nói",
"description": "Khi được bật, Roo sẽ đọc to các phản hồi của nó bằng chức năng chuyển văn bản thành giọng nói.",
"speedLabel": "Tốc độ"
},
"system": {
"label": "Bật thông báo hệ thống",
"description": "Khi được bật, Roo sẽ hiển thị thông báo hệ thống cho các sự kiện và tin nhắn quan trọng.",
"testButton": "Kiểm tra thông báo hệ thống",
"testTitle": "Roo Code",
"testMessage": "Thông báo hệ thống hoạt động bình thường!",
"apiReqFailed": "Lỗi yêu cầu API",
"mistakeLimitReached": "Đã đạt giới hạn lỗi",
"followup": "Đang chờ phản hồi tiếp theo của bạn",
"toolRequest": "Yêu cầu công cụ đang chờ phê duyệt",
"browserAction": "Hành động trình duyệt đang chờ phê duyệt",
"command": "Lệnh đang chờ phê duyệt",
"useMcpServer": "Sử dụng máy chủ MCP để phê duyệt",
"completionResult": "Tác vụ hoàn thành"
}
},
"contextManagement": {

View file

@ -509,6 +509,21 @@
"label": "启用文本转语音",
"description": "启用后Roo 将使用文本转语音功能朗读其响应。",
"speedLabel": "速度"
},
"system": {
"label": "启用系统通知",
"description": "启用后 Roo 将为重要事件和消息显示系统通知。",
"testButton": "测试系统通知",
"testTitle": "Roo Code",
"testMessage": "系统通知运行正常!",
"apiReqFailed": "API 请求错误",
"mistakeLimitReached": "错误次数达到上限",
"followup": "等待你的后续回复",
"toolRequest": "工具请求等待批准",
"browserAction": "浏览器操作等待批准",
"command": "命令等待批准",
"useMcpServer": "使用 MCP 服务进行批准",
"completionResult": "任务完成"
}
},
"contextManagement": {

View file

@ -509,6 +509,21 @@
"label": "啟用文字轉語音",
"description": "啟用後Roo 將使用文字轉語音功能朗讀其回應。",
"speedLabel": "速度"
},
"system": {
"label": "啟用系統通知",
"description": "啟用後Roo 將為重要事件和訊息顯示系統通知。",
"testButton": "測試系統通知",
"testTitle": "Roo Code",
"testMessage": "系統通知運作正常!",
"apiReqFailed": "API 請求錯誤",
"mistakeLimitReached": "錯誤次數達到上限",
"followup": "等待你的後續回覆",
"toolRequest": "工具請求等待核准",
"browserAction": "瀏覽器動作等待核准",
"command": "指令等待核准",
"useMcpServer": "使用 MCP 伺服器進行核准",
"completionResult": "工作完成"
}
},
"contextManagement": {

View file

@ -0,0 +1,11 @@
import { vscode } from "../utils/vscode"
import debounce from "debounce"
export const showSystemNotification = debounce((message: string) => {
vscode.postMessage({
type: "showSystemNotification",
notificationOptions: {
message,
},
})
}, 100)