alvin-bot 4.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/.env.example +43 -0
  2. package/BACKLOG.md +223 -0
  3. package/CHANGELOG.md +63 -0
  4. package/CLAUDE.example.md +152 -0
  5. package/CODE_OF_CONDUCT.md +52 -0
  6. package/CONTRIBUTING.md +72 -0
  7. package/LICENSE +21 -0
  8. package/README.md +529 -0
  9. package/SECURITY.md +38 -0
  10. package/SOUL.example.md +60 -0
  11. package/TOOLS.example.md +42 -0
  12. package/alvin-bot.config.example.json +24 -0
  13. package/bin/cli.js +1088 -0
  14. package/dist/.metadata_never_index +0 -0
  15. package/dist/claude.js +102 -0
  16. package/dist/config.js +65 -0
  17. package/dist/engine.js +90 -0
  18. package/dist/find-claude-binary.js +98 -0
  19. package/dist/handlers/commands.js +1489 -0
  20. package/dist/handlers/document.js +187 -0
  21. package/dist/handlers/message.js +200 -0
  22. package/dist/handlers/photo.js +154 -0
  23. package/dist/handlers/platform-message.js +275 -0
  24. package/dist/handlers/video.js +237 -0
  25. package/dist/handlers/voice.js +148 -0
  26. package/dist/i18n.js +299 -0
  27. package/dist/index.js +442 -0
  28. package/dist/init-data-dir.js +81 -0
  29. package/dist/middleware/auth.js +215 -0
  30. package/dist/migrate.js +139 -0
  31. package/dist/paths.js +87 -0
  32. package/dist/platforms/discord.js +161 -0
  33. package/dist/platforms/index.js +130 -0
  34. package/dist/platforms/signal.js +205 -0
  35. package/dist/platforms/slack.js +318 -0
  36. package/dist/platforms/telegram.js +111 -0
  37. package/dist/platforms/types.js +8 -0
  38. package/dist/platforms/whatsapp.js +648 -0
  39. package/dist/providers/claude-sdk-provider.js +173 -0
  40. package/dist/providers/codex-cli-provider.js +121 -0
  41. package/dist/providers/index.js +7 -0
  42. package/dist/providers/openai-compatible.js +388 -0
  43. package/dist/providers/registry.js +209 -0
  44. package/dist/providers/tool-executor.js +450 -0
  45. package/dist/providers/types.js +205 -0
  46. package/dist/services/access.js +144 -0
  47. package/dist/services/asset-index.js +230 -0
  48. package/dist/services/browser-manager.js +161 -0
  49. package/dist/services/browser.js +121 -0
  50. package/dist/services/compaction.js +129 -0
  51. package/dist/services/cron.js +462 -0
  52. package/dist/services/custom-tools.js +317 -0
  53. package/dist/services/delivery-queue.js +154 -0
  54. package/dist/services/elevenlabs.js +58 -0
  55. package/dist/services/embeddings.js +386 -0
  56. package/dist/services/exec-guard.js +46 -0
  57. package/dist/services/fallback-order.js +151 -0
  58. package/dist/services/heartbeat.js +192 -0
  59. package/dist/services/hooks.js +44 -0
  60. package/dist/services/imagegen.js +72 -0
  61. package/dist/services/language-detect.js +144 -0
  62. package/dist/services/markdown.js +63 -0
  63. package/dist/services/mcp.js +252 -0
  64. package/dist/services/memory.js +133 -0
  65. package/dist/services/personality.js +227 -0
  66. package/dist/services/plugins.js +171 -0
  67. package/dist/services/reminders.js +97 -0
  68. package/dist/services/restart.js +48 -0
  69. package/dist/services/security-audit.js +66 -0
  70. package/dist/services/self-search.js +129 -0
  71. package/dist/services/session.js +93 -0
  72. package/dist/services/skills.js +287 -0
  73. package/dist/services/standing-orders.js +29 -0
  74. package/dist/services/subagents.js +142 -0
  75. package/dist/services/sudo.js +243 -0
  76. package/dist/services/telegram.js +113 -0
  77. package/dist/services/tool-discovery.js +214 -0
  78. package/dist/services/usage-tracker.js +137 -0
  79. package/dist/services/users.js +199 -0
  80. package/dist/services/voice.js +95 -0
  81. package/dist/tui/index.js +507 -0
  82. package/dist/web/canvas.js +30 -0
  83. package/dist/web/doctor-api.js +606 -0
  84. package/dist/web/openai-compat.js +252 -0
  85. package/dist/web/server.js +1351 -0
  86. package/dist/web/setup-api.js +1078 -0
  87. package/docs/mcp.example.json +16 -0
  88. package/docs/screenshots/00-Login.png +0 -0
  89. package/docs/screenshots/01-Chat-Dark-Conversation.png +0 -0
  90. package/docs/screenshots/02-Chat.png +0 -0
  91. package/docs/screenshots/03-Dashboard-Overview.png +0 -0
  92. package/docs/screenshots/04-AI-Models-and-Providers.png +0 -0
  93. package/docs/screenshots/05-Personality-Editor.png +0 -0
  94. package/docs/screenshots/06-Memory-Manager.png +0 -0
  95. package/docs/screenshots/07-Active-Sessions.png +0 -0
  96. package/docs/screenshots/08-File-Browser.png +0 -0
  97. package/docs/screenshots/09-Scheduled-Jobs.png +0 -0
  98. package/docs/screenshots/10-Custom-Tools.png +0 -0
  99. package/docs/screenshots/11-Plugins-and-MCP.png +0 -0
  100. package/docs/screenshots/12-Messaging-Platforms.png +0 -0
  101. package/docs/screenshots/12.1-Messaging-Platforms-WhatsApp-Groups-List.png +0 -0
  102. package/docs/screenshots/12.2-Messaging-Platforms-WA-Group-Details.png +0 -0
  103. package/docs/screenshots/13-User-Management.png +0 -0
  104. package/docs/screenshots/14-Web-Terminal.png +0 -0
  105. package/docs/screenshots/15-Maintenance-and-Health.png +0 -0
  106. package/docs/screenshots/16-Settings-and-Env.png +0 -0
  107. package/docs/screenshots/TG-commands.png +0 -0
  108. package/docs/screenshots/TG.png +0 -0
  109. package/docs/screenshots/_Mac-Installer.png +0 -0
  110. package/docs/tools.example.json +33 -0
  111. package/install.sh +165 -0
  112. package/package.json +190 -0
  113. package/plugins/calendar/index.js +270 -0
  114. package/plugins/email/index.js +231 -0
  115. package/plugins/finance/index.js +254 -0
  116. package/plugins/notes/index.js +227 -0
  117. package/plugins/smarthome/index.js +230 -0
  118. package/plugins/weather/index.js +122 -0
  119. package/skills/apple-notes/SKILL.md +31 -0
  120. package/skills/browse/SKILL.md +136 -0
  121. package/skills/code-project/SKILL.md +43 -0
  122. package/skills/data-analysis/SKILL.md +39 -0
  123. package/skills/document-creation/SKILL.md +48 -0
  124. package/skills/email-summary/SKILL.md +46 -0
  125. package/skills/github/SKILL.md +42 -0
  126. package/skills/summarize/SKILL.md +28 -0
  127. package/skills/system-admin/SKILL.md +39 -0
  128. package/skills/weather/SKILL.md +34 -0
  129. package/skills/web-research/SKILL.md +35 -0
  130. package/web/public/canvas.html +52 -0
  131. package/web/public/css/style.css +555 -0
  132. package/web/public/index.html +189 -0
  133. package/web/public/js/app.js +3102 -0
  134. package/web/public/js/i18n.js +1048 -0
  135. package/web/public/js/icons.js +104 -0
  136. package/web/public/login.html +48 -0
@@ -0,0 +1,1048 @@
1
+ /**
2
+ * Alvin Bot — i18n Bilingual (DE/EN)
3
+ * Simple key-value translation system
4
+ */
5
+
6
+ const STRINGS = {
7
+ de: {
8
+ // General
9
+ 'app.title': 'Alvin Bot',
10
+ 'app.subtitle': 'AI Assistant Dashboard',
11
+ 'connecting': 'Verbinde...',
12
+ 'connected': 'Verbunden',
13
+ 'reconnecting': 'Verbindung wird wiederhergestellt...',
14
+ 'loading': 'Lade...',
15
+ 'save': 'Speichern',
16
+ 'cancel': 'Abbrechen',
17
+ 'delete': 'Löschen',
18
+ 'edit': 'Bearbeiten',
19
+ 'close': 'Schließen',
20
+ 'confirm': 'Bestätigen',
21
+ 'yes': 'Ja',
22
+ 'no': 'Nein',
23
+ 'error': 'Fehler',
24
+ 'success': 'Erfolg',
25
+ 'search': 'Suchen',
26
+ 'reset': 'Zurücksetzen',
27
+ 'back': 'Zurück',
28
+ 'next': 'Weiter',
29
+ 'all': 'Alle',
30
+ 'none': 'Keine',
31
+ 'active': 'Aktiv',
32
+ 'inactive': 'Inaktiv',
33
+ 'enabled': 'Aktiviert',
34
+ 'disabled': 'Deaktiviert',
35
+ 'online': 'Online',
36
+ 'offline': 'Offline',
37
+ 'restart.needed': 'Neustart nötig',
38
+ 'no.data': 'Keine Daten',
39
+
40
+ // Nav sections
41
+ 'nav.main': 'Hauptmenü',
42
+ 'nav.ai': 'KI',
43
+ 'nav.data': 'Daten',
44
+ 'nav.system': 'System',
45
+
46
+ // Nav items
47
+ 'nav.chat': 'Chat',
48
+ 'nav.dashboard': 'Dashboard',
49
+ 'nav.models': 'Modelle',
50
+ 'nav.personality': 'Persönlichkeit',
51
+ 'nav.memory': 'Gedächtnis',
52
+ 'nav.sessions': 'Sessions',
53
+ 'nav.files': 'Dateien',
54
+ 'nav.cron': 'Cron',
55
+ 'nav.tools': 'Tools',
56
+ 'nav.plugins': 'Plugins',
57
+ 'nav.platforms': 'Plattformen',
58
+ 'nav.users': 'Benutzer',
59
+ 'nav.terminal': 'Terminal',
60
+ 'nav.maintenance': 'Wartung',
61
+ 'nav.settings': 'Einstellungen',
62
+
63
+ // Sidebar footer
64
+ 'sidebar.theme': 'Theme',
65
+ 'sidebar.reset': 'Reset',
66
+ 'sidebar.lang': 'Sprache',
67
+
68
+ // Chat
69
+ 'chat.welcome': 'Willkommen bei Alvin Bot! Schreib etwas um zu beginnen.',
70
+ 'chat.placeholder': 'Nachricht eingeben... (Enter = senden, Shift+Enter = Zeile)',
71
+ 'chat.send': 'Senden',
72
+ 'chat.model': 'Model',
73
+ 'chat.effort': 'Effort',
74
+ 'chat.effort.low': 'Low',
75
+ 'chat.effort.medium': 'Medium',
76
+ 'chat.effort.high': 'High',
77
+ 'chat.effort.max': 'Max',
78
+ 'chat.export': 'Export',
79
+ 'chat.export.md': 'Markdown',
80
+ 'chat.export.json': 'JSON',
81
+ 'chat.no.export': 'Kein Chat zum Exportieren',
82
+ 'chat.exported': 'Chat exportiert!',
83
+ 'chat.new.session': 'Neue Session',
84
+ 'chat.session.reset': 'Session zurückgesetzt.',
85
+ 'chat.reply.you': 'Du',
86
+ 'chat.reply.bot': 'Alvin Bot',
87
+ 'chat.reply': 'Antworten',
88
+ 'chat.file.attach': 'Datei anhängen',
89
+ 'chat.file.drop': 'Datei hier ablegen',
90
+ 'chat.tools.used': '{count} Tool(s) verwendet',
91
+ 'chat.fallback': 'Fallback',
92
+
93
+ // Dashboard
94
+ 'dashboard.model': 'Modell',
95
+ 'dashboard.uptime': 'Laufzeit',
96
+ 'dashboard.memory': 'Gedächtnis',
97
+ 'dashboard.memory.days': 'Tage',
98
+ 'dashboard.memory.vectors': 'Vektoren',
99
+ 'dashboard.memory.today': 'heute',
100
+ 'dashboard.tokens': 'Tokens',
101
+ 'dashboard.tokens.in': 'In',
102
+ 'dashboard.tokens.out': 'Out',
103
+ 'dashboard.plugins': 'Plugins',
104
+ 'dashboard.plugins.loaded': 'geladen',
105
+ 'dashboard.mcp': 'MCP',
106
+ 'dashboard.mcp.servers': 'Server',
107
+ 'dashboard.users': 'Benutzer',
108
+ 'dashboard.users.profiles': 'Profile',
109
+
110
+ // Models
111
+ 'models.title': 'KI-Modelle & Provider',
112
+ 'models.desc': 'API Keys einrichten, Modelle aktivieren und Custom Models hinzufügen.',
113
+ 'models.key.set': 'Key gesetzt',
114
+ 'models.key.none': 'Kein Key',
115
+ 'models.free': 'Gratis verfügbar',
116
+ 'models.setup.guide': 'Setup-Anleitung',
117
+ 'models.key.placeholder': 'API Key eingeben...',
118
+ 'models.key.save': 'Speichern',
119
+ 'models.key.test': 'Testen',
120
+ 'models.key.testing': 'Teste...',
121
+ 'models.key.works': 'Key funktioniert!',
122
+ 'models.key.saved': 'Key gespeichert! Bot-Neustart nötig.',
123
+ 'models.key.fill': 'Bitte einen vollständigen Key eingeben',
124
+ 'models.live.title': 'Verfügbare Modelle (live von API laden)',
125
+ 'models.live.loading': 'Modelle werden geladen...',
126
+ 'models.live.none': 'Keine Modelle gefunden oder Key nicht gesetzt.',
127
+ 'models.live.count': '{count} Modelle',
128
+ 'models.live.available': 'Verfügbare Modelle',
129
+ 'models.activate': 'Aktivieren',
130
+ 'models.activated': 'aktiviert!',
131
+ 'models.activate.error': 'Fehler beim Aktivieren',
132
+ 'models.switched': 'Model gewechselt',
133
+ 'models.custom': 'Custom Models',
134
+ 'models.custom.desc': 'Eigene OpenAI-kompatible Endpunkte hinzufügen (LM Studio, vLLM, Together AI, etc.)',
135
+ 'models.custom.add': 'Custom Model hinzufügen',
136
+ 'models.custom.added': 'Custom Model hinzugefügt! Neustart nötig.',
137
+ 'models.custom.fill': 'Bitte alle Pflichtfelder ausfüllen',
138
+ 'models.custom.remove': 'Custom Model "{key}" entfernen?',
139
+ 'models.custom.removed': 'Entfernt',
140
+ 'models.custom.key': 'Eindeutiger Key (z.B. my-llama)',
141
+ 'models.custom.name': 'Anzeigename (z.B. My Llama 3)',
142
+ 'models.custom.model': 'Model ID (z.B. meta-llama/Llama-3-70b)',
143
+ 'models.custom.url': 'Base URL (z.B. http://localhost:1234/v1)',
144
+ 'models.custom.envkey': 'API Key Env-Var (optional)',
145
+ 'models.custom.apikey': 'API Key (optional)',
146
+ 'models.fallback': 'Fallback-Reihenfolge',
147
+ 'models.fallback.desc': 'Wenn der primäre Provider fehlschlägt, werden diese der Reihe nach probiert. Per Pfeile umsortieren.',
148
+ 'models.fallback.primary': 'Primär',
149
+ 'models.fallback.healthy': 'Healthy',
150
+ 'models.fallback.unhealthy': 'Unhealthy',
151
+ 'models.fallback.none': 'Keine Fallback-Provider konfiguriert.',
152
+ 'models.fallback.add': 'Hinzufügen',
153
+ 'models.fallback.added': '{key} hinzugefügt',
154
+ 'models.fallback.removed': '{key} entfernt',
155
+ 'models.provider.add': 'Provider hinzufügen',
156
+ 'models.claude.setup': 'Claude SDK einrichten',
157
+ 'models.claude.installed': 'Installiert',
158
+ 'models.claude.not.installed': 'Nicht installiert',
159
+ 'models.claude.guide.title': 'Claude SDK Setup',
160
+ 'models.claude.guide.step1': '1. CLI installieren: npm install -g @anthropic-ai/claude-code',
161
+ 'models.claude.guide.step2': '2. Anmelden: claude login',
162
+ 'models.claude.guide.step3': '3. Status hier prüfen',
163
+
164
+ // Personality
165
+ 'personality.title': 'Persönlichkeit (SOUL.md)',
166
+ 'personality.desc': 'Definiert wie Alvin Bot spricht und sich verhält. Änderungen werden sofort aktiv.',
167
+ 'personality.save': 'Speichern & Aktivieren',
168
+ 'personality.reload': 'Neu laden',
169
+ 'personality.saved': 'Persönlichkeit aktualisiert!',
170
+ 'personality.placeholder': 'SOUL.md laden...',
171
+
172
+ // Memory
173
+ 'memory.longterm': 'MEMORY.md (Langzeit)',
174
+ 'memory.saved': 'Gespeichert!',
175
+
176
+ // Sessions
177
+ 'sessions.none': 'Keine Sessions',
178
+ 'sessions.none.desc': 'Sessions werden erstellt wenn User chatten.',
179
+ 'sessions.msgs': 'Msgs',
180
+ 'sessions.tools': 'Tools',
181
+ 'sessions.active': 'Aktiv',
182
+ 'sessions.idle': 'Idle',
183
+
184
+ // Plugins
185
+ 'plugins.none': 'Keine Plugins',
186
+ 'plugins.none.desc': 'Plugins in plugins/ ablegen.',
187
+
188
+ // Files
189
+ 'files.new': 'Neue Datei',
190
+ 'files.up': 'Hoch',
191
+ 'files.lines': '{count} Zeilen',
192
+ 'files.binary': 'Binärdatei — kann nicht im Editor geöffnet werden.',
193
+ 'files.open.error': 'Datei kann nicht geöffnet werden',
194
+ 'files.saved': 'Gespeichert!',
195
+ 'files.created': 'Datei erstellt!',
196
+ 'files.create.error': 'Fehler beim Erstellen',
197
+ 'files.delete.confirm': 'Datei löschen?\n\n{path}',
198
+ 'files.deleted': 'Gelöscht!',
199
+ 'files.delete.error': 'Fehler beim Löschen',
200
+ 'files.name.prompt': 'Dateiname (z.B. notes.md):',
201
+
202
+ // Cron
203
+ 'cron.title': 'Cron Jobs',
204
+ 'cron.desc': 'Geplante wiederkehrende oder einmalige Aufgaben.',
205
+ 'cron.create': 'Job erstellen',
206
+ 'cron.none': 'Keine Jobs',
207
+ 'cron.none.desc': 'Erstelle einen Job oben oder via Telegram: /cron add 5m reminder Text',
208
+ 'cron.next.run': 'Nächster Lauf',
209
+ 'cron.runs': 'Runs',
210
+ 'cron.last.run': 'Zuletzt',
211
+ 'cron.never': 'nie',
212
+ 'cron.pause': 'Pause',
213
+ 'cron.start': 'Start',
214
+ 'cron.run.now': 'Jetzt',
215
+ 'cron.edit': 'Bearbeiten',
216
+ 'cron.delete.confirm': 'Job löschen?',
217
+ 'cron.deleted': 'Gelöscht',
218
+ 'cron.created': 'Job erstellt!',
219
+ 'cron.name.required': 'Name ist Pflicht',
220
+ 'cron.updated': 'Timing aktualisiert!',
221
+ 'cron.executed': 'Ausgeführt!',
222
+ 'cron.executing': 'Wird ausgeführt...',
223
+ 'cron.name.placeholder': 'Name (z.B. Health Check)',
224
+ 'cron.payload.placeholder': 'Payload (Text, Command, URL, Prompt)',
225
+ 'cron.type.reminder': 'Reminder',
226
+ 'cron.type.shell': 'Shell Command',
227
+ 'cron.type.http': 'HTTP Request',
228
+ 'cron.type.message': 'Nachricht',
229
+ 'cron.type.ai': 'AI Query',
230
+ 'cron.single': 'Einmalig',
231
+ 'cron.recurring': 'Wiederkehrend',
232
+ 'cron.schedule.repeat': 'Wiederholung',
233
+ 'cron.schedule.interval': 'Intervall',
234
+ 'cron.schedule.daily': 'Täglich',
235
+ 'cron.schedule.weekly': 'Wöchentlich',
236
+ 'cron.schedule.monthly': 'Monatlich',
237
+ 'cron.schedule.every': 'Alle',
238
+ 'cron.schedule.at': 'Um',
239
+ 'cron.schedule.oclock': 'Uhr',
240
+ 'cron.schedule.onday': 'Am',
241
+ 'cron.schedule.ofmonth': '. des Monats',
242
+ 'cron.schedule.type': 'Typ',
243
+ 'cron.schedule.weekday.min': 'Mindestens einen Wochentag wählen',
244
+ 'cron.weekdays': 'So,Mo,Di,Mi,Do,Fr,Sa',
245
+ 'cron.units.seconds': 'Sekunden',
246
+ 'cron.units.minutes': 'Minuten',
247
+ 'cron.units.hours': 'Stunden',
248
+ 'cron.units.days': 'Tage',
249
+
250
+ // Tools
251
+ 'tools.search.placeholder': 'Tool suchen...',
252
+ 'tools.count': '{count} Tools',
253
+ 'tools.none': 'Keine Tools',
254
+ 'tools.none.desc': 'Tools in TOOLS.md konfigurieren.',
255
+ 'tools.running': 'Running {name}...',
256
+ 'tools.executed': 'Tool ausgeführt!',
257
+ 'tools.cat.system': 'System',
258
+ 'tools.cat.email': 'Email',
259
+ 'tools.cat.automation': 'Automation',
260
+ 'tools.cat.pdf': 'PDF',
261
+ 'tools.cat.dev': 'Dev Tools',
262
+ 'tools.cat.network': 'Netzwerk',
263
+ 'tools.cat.media': 'Medien',
264
+ 'tools.cat.clipboard': 'Zwischenablage',
265
+ 'tools.cat.files': 'Dateien',
266
+ 'tools.cat.other': 'Sonstige',
267
+
268
+ // Users
269
+ 'users.none': 'Keine Benutzer',
270
+ 'users.none.desc': 'Werden automatisch erfasst sobald jemand schreibt.',
271
+ 'users.kill.confirm': 'User "{name}" wirklich löschen?\n\nDas löscht:\n• Aktive Session (+ laufende Anfrage)\n• Profil-Daten\n• Chat-History\n• Memory-Verzeichnis\n\nDiese Aktion kann nicht rückgängig gemacht werden!',
272
+ 'users.deleted': 'User gelöscht.',
273
+ 'users.deleted.summary': 'Gelöscht: {items}',
274
+ 'users.nothing': 'Nichts zu löschen',
275
+ 'users.no.session': 'Keine aktive Session',
276
+ 'users.processing': 'Verarbeitet...',
277
+ 'users.query.active': 'Query aktiv',
278
+ 'users.in.queue': '{count} in Queue',
279
+ 'users.cost': 'Kosten',
280
+ 'users.msgs': 'Nachrichten',
281
+ 'users.tools': 'Tools',
282
+ 'users.history': 'History',
283
+ 'users.effort': 'Effort',
284
+ 'users.just.now': 'gerade eben',
285
+ 'users.min.ago': 'vor {n} Min',
286
+ 'users.hrs.ago': 'vor {n} Std',
287
+ 'users.messages.total': '{n} Nachrichten',
288
+ 'users.last.active': 'Zuletzt aktiv',
289
+ 'users.platform.unknown': 'Unbekannt',
290
+
291
+ // Platforms
292
+ 'platforms.title': 'Messaging-Plattformen',
293
+ 'platforms.desc': 'Verbinde Alvin Bot mit verschiedenen Messaging-Diensten. Mehrere gleichzeitig möglich.',
294
+ 'platforms.ready': 'Bereit',
295
+ 'platforms.deps.missing': 'Deps fehlen',
296
+ 'platforms.not.configured': 'Nicht eingerichtet',
297
+ 'platforms.setup.guide': 'Setup-Anleitung',
298
+ 'platforms.save': 'Speichern',
299
+ 'platforms.saved': 'Gespeichert!',
300
+ 'platforms.saved.restart': 'Gespeichert! Neustart nötig für Änderungen.',
301
+ 'platforms.install.deps': 'Dependencies installieren',
302
+ 'platforms.installing': 'Installiere Dependencies...',
303
+ 'platforms.installed': 'Dependencies installiert!',
304
+ 'platforms.test': 'Verbindung testen',
305
+ 'platforms.testing': 'Teste...',
306
+ 'platforms.connected': 'Verbunden',
307
+ 'platforms.disable': 'Deaktivieren',
308
+ 'platforms.disable.confirm': '{id} wirklich deaktivieren?',
309
+ 'platforms.disabled': 'Plattform deaktiviert. Neustart nötig.',
310
+ 'platforms.status.connected': 'Verbunden',
311
+ 'platforms.status.connecting': 'Verbinde...',
312
+ 'platforms.status.qr': 'QR-Code scannen!',
313
+ 'platforms.status.error': 'Fehler',
314
+ 'platforms.status.disconnected': 'Nicht verbunden',
315
+ 'platforms.status.logged.out': 'Abgemeldet',
316
+
317
+ // WhatsApp
318
+ 'wa.status.loading': 'Status wird geladen...',
319
+ 'wa.check.status': 'Status prüfen',
320
+ 'wa.disconnect': 'Trennen & Reset',
321
+ 'wa.disconnect.confirm': 'WhatsApp-Verbindung trennen und Auth-Daten löschen?\n\nDu musst danach erneut den QR-Code scannen.',
322
+ 'wa.disconnected': 'Auth-Daten gelöscht. Bitte Bot neustarten.',
323
+ 'wa.scan.qr': 'Scanne mit WhatsApp → Verknüpfte Geräte → Gerät hinzufügen',
324
+ 'wa.qr.ready': 'QR-Code bereit — jetzt scannen!',
325
+ 'wa.qr.available': 'QR bereit',
326
+ 'wa.not.connected': 'WhatsApp nicht verbunden — zuerst oben verbinden.',
327
+ 'wa.groups': 'Gruppen-Verwaltung',
328
+ 'wa.groups.loading': 'Lade WhatsApp-Gruppen...',
329
+ 'wa.groups.count': '{count} Gruppen',
330
+ 'wa.groups.active': '{count} aktiv',
331
+ 'wa.groups.participants': '{count} Teilnehmer',
332
+ 'wa.groups.enabled': '{name} aktiviert',
333
+ 'wa.groups.disabled': '{name} deaktiviert',
334
+ 'wa.groups.configured': '{name} konfiguriert und aktiviert!',
335
+ 'wa.groups.rule.deleted': 'Regel gelöscht',
336
+ 'wa.groups.rule.delete.confirm': 'Regel für diese Gruppe löschen?',
337
+ 'wa.groups.no.config': 'Nicht konfiguriert',
338
+ 'wa.groups.allowed': '{count} erlaubte Kontakte',
339
+ 'wa.groups.all.allowed': 'Alle Teilnehmer erlaubt',
340
+ 'wa.groups.mention.required': '@ Erwähnung erforderlich',
341
+ 'wa.groups.all.messages': 'Alle Nachrichten',
342
+ 'wa.groups.media': 'Medien verarbeiten',
343
+ 'wa.groups.approval': 'Approval vor Verarbeitung',
344
+ 'wa.groups.allowed.contacts': 'Erlaubte Kontakte',
345
+ 'wa.groups.select.all': 'Alle',
346
+ 'wa.groups.select.none': 'Keine',
347
+ 'wa.groups.no.selection': 'Keine Auswahl = alle dürfen ansprechen',
348
+ 'wa.groups.admin': 'Admin',
349
+ 'wa.approval': 'Approval',
350
+ 'wa.auto': 'Auto',
351
+
352
+ // Terminal
353
+ 'terminal.placeholder': 'Befehl eingeben...',
354
+ 'terminal.run': 'Ausführen',
355
+
356
+ // Settings
357
+ 'settings.sudo': 'Sudo / Admin-Rechte',
358
+ 'settings.sudo.desc': 'Erlaube Alvin Bot, Befehle mit Administratorrechten auszuführen',
359
+ 'settings.sudo.active': 'Aktiv & verifiziert',
360
+ 'settings.sudo.configured': 'Konfiguriert, Verifikation nötig',
361
+ 'settings.sudo.not.set': 'Nicht eingerichtet',
362
+ 'settings.sudo.status': 'Status',
363
+ 'settings.sudo.storage': 'Speicher',
364
+ 'settings.sudo.system': 'System',
365
+ 'settings.sudo.accessibility': 'Accessibility',
366
+ 'settings.sudo.fda': 'Full Disk Access',
367
+ 'settings.sudo.open': 'Öffnen',
368
+ 'settings.sudo.password': 'System-Passwort eingeben...',
369
+ 'settings.sudo.setup': 'Einrichten',
370
+ 'settings.sudo.stored.secure': 'Das Passwort wird sicher gespeichert — nie im Klartext.',
371
+ 'settings.sudo.setup.ok': 'Sudo eingerichtet & verifiziert!',
372
+ 'settings.sudo.verify': 'Verifizieren',
373
+ 'settings.sudo.verifying': 'Verifiziere...',
374
+ 'settings.sudo.verified': 'Sudo funktioniert!',
375
+ 'settings.sudo.test': 'Test-Command',
376
+ 'settings.sudo.test.prompt': 'Sudo-Befehl zum Testen:',
377
+ 'settings.sudo.admin.dialog': 'Admin-Dialog',
378
+ 'settings.sudo.admin.reason': 'Grund für Admin-Rechte:',
379
+ 'settings.sudo.admin.default.reason': 'Alvin Bot benötigt Administrator-Rechte',
380
+ 'settings.sudo.admin.showing': 'macOS Admin-Dialog wird angezeigt...',
381
+ 'settings.sudo.admin.confirmed': 'Bestätigt!',
382
+ 'settings.sudo.admin.denied': 'Abgelehnt oder Fehler',
383
+ 'settings.sudo.revoke': 'Widerrufen',
384
+ 'settings.sudo.revoke.confirm': 'Sudo-Zugriff wirklich widerrufen? Gespeichertes Passwort wird gelöscht.',
385
+ 'settings.sudo.revoked': 'Sudo-Zugriff widerrufen',
386
+ 'settings.sudo.executing': 'Ausführen...',
387
+ 'settings.sudo.output': 'Output',
388
+ 'settings.env': 'Environment Variables',
389
+ 'settings.env.add': 'Variable hinzufügen',
390
+ 'settings.env.name.prompt': 'Variable Name (z.B. DISCORD_TOKEN):',
391
+ 'settings.env.value.prompt': 'Wert für {key}:',
392
+ 'settings.env.new.prompt': 'Neuer Wert für {key}:',
393
+ 'settings.env.saved': '{key} gespeichert! Neustart nötig.',
394
+ 'settings.env.added': '{key} hinzugefügt!',
395
+ 'settings.sysopen': 'Systemeinstellungen geöffnet',
396
+
397
+ // Maintenance
398
+ 'maint.doctor': 'System-Doktor',
399
+ 'maint.doctor.errors': '{errors} Fehler, {warns} Warnungen',
400
+ 'maint.doctor.check': 'Prüfen',
401
+ 'maint.doctor.fix.all': 'Alles reparieren',
402
+ 'maint.doctor.fix.all.confirm': 'Alle Probleme automatisch reparieren?',
403
+ 'maint.doctor.fixed': '{ok} repariert',
404
+ 'maint.doctor.failed': '{fail} fehlgeschlagen',
405
+ 'maint.backup': 'Backup & Wiederherstellung',
406
+ 'maint.backup.desc': 'Sichere und stelle Config, Memory, Tools, SOUL.md wieder her',
407
+ 'maint.backup.create': 'Backup erstellen',
408
+ 'maint.backup.creating': 'Erstelle Backup...',
409
+ 'maint.backup.name.prompt': 'Backup-Name (optional):',
410
+ 'maint.backup.created': 'Backup "{id}" erstellt ({count} Dateien)',
411
+ 'maint.backup.files': 'Dateien',
412
+ 'maint.backup.files.in': 'Dateien in {id}',
413
+ 'maint.backup.restore': 'Wiederherstellen',
414
+ 'maint.backup.restore.confirm': 'Backup "{id}" wiederherstellen?\n\nAktuelle Config-Dateien werden überschrieben!\nBot-Neustart nötig danach.',
415
+ 'maint.backup.restored': '{count} Dateien wiederhergestellt! Bot-Neustart nötig.',
416
+ 'maint.backup.delete.confirm': 'Backup "{id}" unwiderruflich löschen?',
417
+ 'maint.backup.deleted': 'Gelöscht',
418
+ 'maint.backup.none': 'Noch keine Backups vorhanden.',
419
+ 'maint.pm2': 'Prozess-Steuerung (PM2)',
420
+ 'maint.pm2.desc': 'Bot-Prozess starten, stoppen und überwachen',
421
+ 'maint.pm2.status': 'Status',
422
+ 'maint.pm2.loading': 'Lade PM2-Status...',
423
+ 'maint.pm2.unreachable': 'Nicht erreichbar',
424
+ 'maint.pm2.restart': 'Restart',
425
+ 'maint.pm2.restart.confirm': 'Bot neustarten? Laufende Anfragen werden abgebrochen.',
426
+ 'maint.pm2.reload': 'Reload',
427
+ 'maint.pm2.stop': 'Stop',
428
+ 'maint.pm2.stop.confirm': 'Bot wirklich stoppen? Der Bot wird offline gehen!',
429
+ 'maint.pm2.start': 'Start',
430
+ 'maint.pm2.flush': 'Logs leeren',
431
+ 'maint.pm2.action.ok': 'PM2 {action} erfolgreich',
432
+ 'maint.pm2.action.fail': 'PM2 {action} fehlgeschlagen',
433
+ 'maint.pm2.lost': 'Verbindung verloren (Bot gestoppt?)',
434
+ 'maint.logs': 'Letzte Logs',
435
+ 'maint.logs.desc': 'Die letzten 30 Zeilen der Bot-Ausgabe',
436
+ 'maint.logs.refresh': 'Aktualisieren',
437
+ 'maint.logs.load': 'Klicke "Aktualisieren" um Logs zu laden.',
438
+ 'maint.bot.restart': 'Bot neustarten',
439
+ 'maint.bot.restart.confirm': 'Bot wirklich neustarten? Laufende Anfragen werden abgebrochen.',
440
+ 'maint.bot.restarting': 'Bot wird neugestartet...',
441
+ 'maint.bot.reconnecting': 'Bot sollte gleich wieder verfügbar sein...',
442
+
443
+ // Command Palette
444
+ 'cmd.title': 'Befehlspalette',
445
+ 'cmd.placeholder': 'Suche Seiten, Aktionen...',
446
+ 'cmd.goto': 'Gehe zu',
447
+ 'cmd.actions': 'Aktionen',
448
+ 'cmd.action.reset': 'Chat zurücksetzen',
449
+ 'cmd.action.theme': 'Theme wechseln',
450
+ 'cmd.action.export': 'Chat exportieren',
451
+ 'cmd.action.lang': 'Sprache wechseln',
452
+ 'cmd.no.results': 'Keine Ergebnisse',
453
+
454
+ // Provider Add
455
+ 'provider.add.title': 'Provider hinzufügen',
456
+ 'provider.add.desc': 'Neuen KI-Provider konfigurieren und aktivieren.',
457
+ 'provider.add.select': 'Provider auswählen',
458
+ 'provider.add.key': 'API Key',
459
+ 'provider.add.test': 'Key testen',
460
+ 'provider.add.save': 'Speichern & Aktivieren',
461
+ 'provider.add.chain': 'In Fallback-Chain einsortieren',
462
+
463
+ // Claude SDK
464
+ 'claude.sdk.title': 'Claude SDK einrichten',
465
+ 'claude.sdk.checking': 'Prüfe CLI-Installation...',
466
+ 'claude.sdk.step1': 'Schritt 1: CLI installieren',
467
+ 'claude.sdk.step1.cmd': 'npm install -g @anthropic-ai/claude-code',
468
+ 'claude.sdk.step2': 'Schritt 2: Anmelden',
469
+ 'claude.sdk.step2.cmd': 'claude login',
470
+ 'claude.sdk.step3': 'Schritt 3: Status prüfen',
471
+
472
+ // Setup Wizard
473
+ 'wizard.title': 'Willkommen bei Alvin Bot!',
474
+ 'wizard.subtitle': 'In 3 einfachen Schritten ist dein AI-Assistent einsatzbereit.',
475
+ 'wizard.step': 'Schritt {n} von {total}',
476
+ 'wizard.step1.title': 'Telegram Bot erstellen',
477
+ 'wizard.step1.desc': 'Erstelle deinen eigenen Bot bei Telegram.',
478
+ 'wizard.step1.instruction1': '1. Öffne Telegram und suche nach',
479
+ 'wizard.step1.instruction2': '2. Sende /newbot und wähle einen Namen',
480
+ 'wizard.step1.instruction3': '3. Kopiere den Bot-Token hierher',
481
+ 'wizard.step1.token.placeholder': 'Bot-Token einfügen (z.B. 123456:ABC-DEF...)',
482
+ 'wizard.step1.token.validate': 'Token prüfen',
483
+ 'wizard.step1.token.valid': 'Bot gefunden:',
484
+ 'wizard.step1.token.invalid': 'Ungültiger Token',
485
+ 'wizard.step1.userid': 'Deine Telegram User-ID',
486
+ 'wizard.step1.userid.placeholder': 'Deine User-ID (z.B. 123456789)',
487
+ 'wizard.step1.userid.help': 'Sende eine Nachricht an @userinfobot um deine ID zu erfahren.',
488
+ 'wizard.step2.title': 'KI-Provider wählen',
489
+ 'wizard.step2.desc': 'Wähle welche KI deinen Bot antreiben soll.',
490
+ 'wizard.step2.recommended': 'Empfohlen',
491
+ 'wizard.step2.free': 'Kostenlos',
492
+ 'wizard.step2.premium': 'Premium',
493
+ 'wizard.step2.key.placeholder': 'API Key eingeben...',
494
+ 'wizard.step3.title': 'Fast geschafft!',
495
+ 'wizard.step3.desc': 'Optionale Einstellungen — kannst du auch später ändern.',
496
+ 'wizard.step3.password': 'Web-Dashboard Passwort (optional)',
497
+ 'wizard.step3.password.placeholder': 'Passwort für dieses Dashboard',
498
+ 'wizard.step3.password.help': 'Schützt den Zugang zu diesem Dashboard. Leer lassen = offener Zugang.',
499
+ 'wizard.finish': 'Setup abschließen',
500
+ 'wizard.finish.success': 'Setup abgeschlossen! Bot wird neugestartet...',
501
+ 'wizard.finish.restart': 'Bitte starte den Bot neu: pm2 restart alvin-bot',
502
+ 'wizard.skip': 'Überspringen',
503
+ 'wizard.back': 'Zurück',
504
+ 'wizard.next': 'Weiter',
505
+ },
506
+
507
+ en: {
508
+ // General
509
+ 'app.title': 'Alvin Bot',
510
+ 'app.subtitle': 'AI Assistant Dashboard',
511
+ 'connecting': 'Connecting...',
512
+ 'connected': 'Connected',
513
+ 'reconnecting': 'Reconnecting...',
514
+ 'loading': 'Loading...',
515
+ 'save': 'Save',
516
+ 'cancel': 'Cancel',
517
+ 'delete': 'Delete',
518
+ 'edit': 'Edit',
519
+ 'close': 'Close',
520
+ 'confirm': 'Confirm',
521
+ 'yes': 'Yes',
522
+ 'no': 'No',
523
+ 'error': 'Error',
524
+ 'success': 'Success',
525
+ 'search': 'Search',
526
+ 'reset': 'Reset',
527
+ 'back': 'Back',
528
+ 'next': 'Next',
529
+ 'all': 'All',
530
+ 'none': 'None',
531
+ 'active': 'Active',
532
+ 'inactive': 'Inactive',
533
+ 'enabled': 'Enabled',
534
+ 'disabled': 'Disabled',
535
+ 'online': 'Online',
536
+ 'offline': 'Offline',
537
+ 'restart.needed': 'Restart required',
538
+ 'no.data': 'No data',
539
+
540
+ // Nav sections
541
+ 'nav.main': 'Main',
542
+ 'nav.ai': 'AI',
543
+ 'nav.data': 'Data',
544
+ 'nav.system': 'System',
545
+
546
+ // Nav items
547
+ 'nav.chat': 'Chat',
548
+ 'nav.dashboard': 'Dashboard',
549
+ 'nav.models': 'Models',
550
+ 'nav.personality': 'Personality',
551
+ 'nav.memory': 'Memory',
552
+ 'nav.sessions': 'Sessions',
553
+ 'nav.files': 'Files',
554
+ 'nav.cron': 'Cron',
555
+ 'nav.tools': 'Tools',
556
+ 'nav.plugins': 'Plugins',
557
+ 'nav.platforms': 'Platforms',
558
+ 'nav.users': 'Users',
559
+ 'nav.terminal': 'Terminal',
560
+ 'nav.maintenance': 'Maintenance',
561
+ 'nav.settings': 'Settings',
562
+
563
+ // Sidebar footer
564
+ 'sidebar.theme': 'Theme',
565
+ 'sidebar.reset': 'Reset',
566
+ 'sidebar.lang': 'Language',
567
+
568
+ // Chat
569
+ 'chat.welcome': 'Welcome to Alvin Bot! Type something to get started.',
570
+ 'chat.placeholder': 'Type a message... (Enter = send, Shift+Enter = newline)',
571
+ 'chat.send': 'Send',
572
+ 'chat.model': 'Model',
573
+ 'chat.effort': 'Effort',
574
+ 'chat.effort.low': 'Low',
575
+ 'chat.effort.medium': 'Medium',
576
+ 'chat.effort.high': 'High',
577
+ 'chat.effort.max': 'Max',
578
+ 'chat.export': 'Export',
579
+ 'chat.export.md': 'Markdown',
580
+ 'chat.export.json': 'JSON',
581
+ 'chat.no.export': 'No chat to export',
582
+ 'chat.exported': 'Chat exported!',
583
+ 'chat.new.session': 'New session',
584
+ 'chat.session.reset': 'Session reset.',
585
+ 'chat.reply.you': 'You',
586
+ 'chat.reply.bot': 'Alvin Bot',
587
+ 'chat.reply': 'Reply',
588
+ 'chat.file.attach': 'Attach file',
589
+ 'chat.file.drop': 'Drop file here',
590
+ 'chat.tools.used': '{count} Tool(s) used',
591
+ 'chat.fallback': 'Fallback',
592
+
593
+ // Dashboard
594
+ 'dashboard.model': 'Model',
595
+ 'dashboard.uptime': 'Uptime',
596
+ 'dashboard.memory': 'Memory',
597
+ 'dashboard.memory.days': 'Days',
598
+ 'dashboard.memory.vectors': 'Vectors',
599
+ 'dashboard.memory.today': 'today',
600
+ 'dashboard.tokens': 'Tokens',
601
+ 'dashboard.tokens.in': 'In',
602
+ 'dashboard.tokens.out': 'Out',
603
+ 'dashboard.plugins': 'Plugins',
604
+ 'dashboard.plugins.loaded': 'loaded',
605
+ 'dashboard.mcp': 'MCP',
606
+ 'dashboard.mcp.servers': 'Servers',
607
+ 'dashboard.users': 'Users',
608
+ 'dashboard.users.profiles': 'Profiles',
609
+
610
+ // Models
611
+ 'models.title': 'AI Models & Providers',
612
+ 'models.desc': 'Set up API keys, activate models and add custom models.',
613
+ 'models.key.set': 'Key set',
614
+ 'models.key.none': 'No Key',
615
+ 'models.free': 'Free available',
616
+ 'models.setup.guide': 'Setup Guide',
617
+ 'models.key.placeholder': 'Enter API Key...',
618
+ 'models.key.save': 'Save',
619
+ 'models.key.test': 'Test',
620
+ 'models.key.testing': 'Testing...',
621
+ 'models.key.works': 'Key works!',
622
+ 'models.key.saved': 'Key saved! Bot restart needed.',
623
+ 'models.key.fill': 'Please enter a complete key',
624
+ 'models.live.title': 'Available Models (load live from API)',
625
+ 'models.live.loading': 'Loading models...',
626
+ 'models.live.none': 'No models found or key not set.',
627
+ 'models.live.count': '{count} Models',
628
+ 'models.live.available': 'Available Models',
629
+ 'models.activate': 'Activate',
630
+ 'models.activated': 'activated!',
631
+ 'models.activate.error': 'Error activating',
632
+ 'models.switched': 'Model switched',
633
+ 'models.custom': 'Custom Models',
634
+ 'models.custom.desc': 'Add your own OpenAI-compatible endpoints (LM Studio, vLLM, Together AI, etc.)',
635
+ 'models.custom.add': 'Add Custom Model',
636
+ 'models.custom.added': 'Custom Model added! Restart needed.',
637
+ 'models.custom.fill': 'Please fill all required fields',
638
+ 'models.custom.remove': 'Remove custom model "{key}"?',
639
+ 'models.custom.removed': 'Removed',
640
+ 'models.custom.key': 'Unique Key (e.g. my-llama)',
641
+ 'models.custom.name': 'Display Name (e.g. My Llama 3)',
642
+ 'models.custom.model': 'Model ID (e.g. meta-llama/Llama-3-70b)',
643
+ 'models.custom.url': 'Base URL (e.g. http://localhost:1234/v1)',
644
+ 'models.custom.envkey': 'API Key Env Var (optional)',
645
+ 'models.custom.apikey': 'API Key (optional)',
646
+ 'models.fallback': 'Fallback Order',
647
+ 'models.fallback.desc': 'When the primary provider fails, these are tried in order. Use arrows to reorder.',
648
+ 'models.fallback.primary': 'Primary',
649
+ 'models.fallback.healthy': 'Healthy',
650
+ 'models.fallback.unhealthy': 'Unhealthy',
651
+ 'models.fallback.none': 'No fallback providers configured.',
652
+ 'models.fallback.add': 'Add',
653
+ 'models.fallback.added': '{key} added',
654
+ 'models.fallback.removed': '{key} removed',
655
+ 'models.provider.add': 'Add Provider',
656
+ 'models.claude.setup': 'Set up Claude SDK',
657
+ 'models.claude.installed': 'Installed',
658
+ 'models.claude.not.installed': 'Not installed',
659
+ 'models.claude.guide.title': 'Claude SDK Setup',
660
+ 'models.claude.guide.step1': '1. Install CLI: npm install -g @anthropic-ai/claude-code',
661
+ 'models.claude.guide.step2': '2. Login: claude login',
662
+ 'models.claude.guide.step3': '3. Check status here',
663
+
664
+ // Personality
665
+ 'personality.title': 'Personality (SOUL.md)',
666
+ 'personality.desc': 'Defines how Alvin Bot speaks and behaves. Changes take effect immediately.',
667
+ 'personality.save': 'Save & Activate',
668
+ 'personality.reload': 'Reload',
669
+ 'personality.saved': 'Personality updated!',
670
+ 'personality.placeholder': 'Loading SOUL.md...',
671
+
672
+ // Memory
673
+ 'memory.longterm': 'MEMORY.md (Long-term)',
674
+ 'memory.saved': 'Saved!',
675
+
676
+ // Sessions
677
+ 'sessions.none': 'No Sessions',
678
+ 'sessions.none.desc': 'Sessions are created when users chat.',
679
+ 'sessions.msgs': 'Msgs',
680
+ 'sessions.tools': 'Tools',
681
+ 'sessions.active': 'Active',
682
+ 'sessions.idle': 'Idle',
683
+
684
+ // Plugins
685
+ 'plugins.none': 'No Plugins',
686
+ 'plugins.none.desc': 'Place plugins in plugins/ folder.',
687
+
688
+ // Files
689
+ 'files.new': 'New File',
690
+ 'files.up': 'Up',
691
+ 'files.lines': '{count} lines',
692
+ 'files.binary': 'Binary file — cannot be opened in editor.',
693
+ 'files.open.error': 'Cannot open file',
694
+ 'files.saved': 'Saved!',
695
+ 'files.created': 'File created!',
696
+ 'files.create.error': 'Error creating file',
697
+ 'files.delete.confirm': 'Delete file?\n\n{path}',
698
+ 'files.deleted': 'Deleted!',
699
+ 'files.delete.error': 'Error deleting file',
700
+ 'files.name.prompt': 'File name (e.g. notes.md):',
701
+
702
+ // Cron
703
+ 'cron.title': 'Cron Jobs',
704
+ 'cron.desc': 'Scheduled recurring or one-time tasks.',
705
+ 'cron.create': 'Create Job',
706
+ 'cron.none': 'No Jobs',
707
+ 'cron.none.desc': 'Create a job above or via Telegram: /cron add 5m reminder Text',
708
+ 'cron.next.run': 'Next run',
709
+ 'cron.runs': 'Runs',
710
+ 'cron.last.run': 'Last',
711
+ 'cron.never': 'never',
712
+ 'cron.pause': 'Pause',
713
+ 'cron.start': 'Start',
714
+ 'cron.run.now': 'Now',
715
+ 'cron.edit': 'Edit',
716
+ 'cron.delete.confirm': 'Delete job?',
717
+ 'cron.deleted': 'Deleted',
718
+ 'cron.created': 'Job created!',
719
+ 'cron.name.required': 'Name is required',
720
+ 'cron.updated': 'Schedule updated!',
721
+ 'cron.executed': 'Executed!',
722
+ 'cron.executing': 'Executing...',
723
+ 'cron.name.placeholder': 'Name (e.g. Health Check)',
724
+ 'cron.payload.placeholder': 'Payload (Text, Command, URL, Prompt)',
725
+ 'cron.type.reminder': 'Reminder',
726
+ 'cron.type.shell': 'Shell Command',
727
+ 'cron.type.http': 'HTTP Request',
728
+ 'cron.type.message': 'Message',
729
+ 'cron.type.ai': 'AI Query',
730
+ 'cron.single': 'One-time',
731
+ 'cron.recurring': 'Recurring',
732
+ 'cron.schedule.repeat': 'Repeat',
733
+ 'cron.schedule.interval': 'Interval',
734
+ 'cron.schedule.daily': 'Daily',
735
+ 'cron.schedule.weekly': 'Weekly',
736
+ 'cron.schedule.monthly': 'Monthly',
737
+ 'cron.schedule.every': 'Every',
738
+ 'cron.schedule.at': 'At',
739
+ 'cron.schedule.oclock': '',
740
+ 'cron.schedule.onday': 'On the',
741
+ 'cron.schedule.ofmonth': 'of the month',
742
+ 'cron.schedule.type': 'Type',
743
+ 'cron.schedule.weekday.min': 'Select at least one weekday',
744
+ 'cron.weekdays': 'Sun,Mon,Tue,Wed,Thu,Fri,Sat',
745
+ 'cron.units.seconds': 'Seconds',
746
+ 'cron.units.minutes': 'Minutes',
747
+ 'cron.units.hours': 'Hours',
748
+ 'cron.units.days': 'Days',
749
+
750
+ // Tools
751
+ 'tools.search.placeholder': 'Search tools...',
752
+ 'tools.count': '{count} Tools',
753
+ 'tools.none': 'No Tools',
754
+ 'tools.none.desc': 'Configure tools in TOOLS.md.',
755
+ 'tools.running': 'Running {name}...',
756
+ 'tools.executed': 'Tool executed!',
757
+ 'tools.cat.system': 'System',
758
+ 'tools.cat.email': 'Email',
759
+ 'tools.cat.automation': 'Automation',
760
+ 'tools.cat.pdf': 'PDF',
761
+ 'tools.cat.dev': 'Dev Tools',
762
+ 'tools.cat.network': 'Network',
763
+ 'tools.cat.media': 'Media',
764
+ 'tools.cat.clipboard': 'Clipboard',
765
+ 'tools.cat.files': 'Files',
766
+ 'tools.cat.other': 'Other',
767
+
768
+ // Users
769
+ 'users.none': 'No Users',
770
+ 'users.none.desc': 'Users are automatically tracked when someone writes.',
771
+ 'users.kill.confirm': 'Really delete user "{name}"?\n\nThis deletes:\n• Active session (+ running query)\n• Profile data\n• Chat history\n• Memory directory\n\nThis action cannot be undone!',
772
+ 'users.deleted': 'User deleted.',
773
+ 'users.deleted.summary': 'Deleted: {items}',
774
+ 'users.nothing': 'Nothing to delete',
775
+ 'users.no.session': 'No active session',
776
+ 'users.processing': 'Processing...',
777
+ 'users.query.active': 'Query active',
778
+ 'users.in.queue': '{count} in queue',
779
+ 'users.cost': 'Cost',
780
+ 'users.msgs': 'Messages',
781
+ 'users.tools': 'Tools',
782
+ 'users.history': 'History',
783
+ 'users.effort': 'Effort',
784
+ 'users.just.now': 'just now',
785
+ 'users.min.ago': '{n} min ago',
786
+ 'users.hrs.ago': '{n} hrs ago',
787
+ 'users.messages.total': '{n} messages',
788
+ 'users.last.active': 'Last active',
789
+ 'users.platform.unknown': 'Unknown',
790
+
791
+ // Platforms
792
+ 'platforms.title': 'Messaging Platforms',
793
+ 'platforms.desc': 'Connect Alvin Bot with various messaging services. Multiple can be active.',
794
+ 'platforms.ready': 'Ready',
795
+ 'platforms.deps.missing': 'Deps missing',
796
+ 'platforms.not.configured': 'Not configured',
797
+ 'platforms.setup.guide': 'Setup Guide',
798
+ 'platforms.save': 'Save',
799
+ 'platforms.saved': 'Saved!',
800
+ 'platforms.saved.restart': 'Saved! Restart needed for changes.',
801
+ 'platforms.install.deps': 'Install Dependencies',
802
+ 'platforms.installing': 'Installing dependencies...',
803
+ 'platforms.installed': 'Dependencies installed!',
804
+ 'platforms.test': 'Test Connection',
805
+ 'platforms.testing': 'Testing...',
806
+ 'platforms.connected': 'Connected',
807
+ 'platforms.disable': 'Disable',
808
+ 'platforms.disable.confirm': 'Really disable {id}?',
809
+ 'platforms.disabled': 'Platform disabled. Restart needed.',
810
+ 'platforms.status.connected': 'Connected',
811
+ 'platforms.status.connecting': 'Connecting...',
812
+ 'platforms.status.qr': 'Scan QR Code!',
813
+ 'platforms.status.error': 'Error',
814
+ 'platforms.status.disconnected': 'Not connected',
815
+ 'platforms.status.logged.out': 'Logged out',
816
+
817
+ // WhatsApp
818
+ 'wa.status.loading': 'Loading status...',
819
+ 'wa.check.status': 'Check Status',
820
+ 'wa.disconnect': 'Disconnect & Reset',
821
+ 'wa.disconnect.confirm': 'Disconnect WhatsApp and delete auth data?\n\nYou\'ll need to scan the QR code again.',
822
+ 'wa.disconnected': 'Auth data deleted. Please restart bot.',
823
+ 'wa.scan.qr': 'Scan with WhatsApp → Linked Devices → Link a Device',
824
+ 'wa.qr.ready': 'QR code ready — scan now!',
825
+ 'wa.qr.available': 'QR ready',
826
+ 'wa.not.connected': 'WhatsApp not connected — connect above first.',
827
+ 'wa.groups': 'Group Management',
828
+ 'wa.groups.loading': 'Loading WhatsApp groups...',
829
+ 'wa.groups.count': '{count} groups',
830
+ 'wa.groups.active': '{count} active',
831
+ 'wa.groups.participants': '{count} participants',
832
+ 'wa.groups.enabled': '{name} enabled',
833
+ 'wa.groups.disabled': '{name} disabled',
834
+ 'wa.groups.configured': '{name} configured and enabled!',
835
+ 'wa.groups.rule.deleted': 'Rule deleted',
836
+ 'wa.groups.rule.delete.confirm': 'Delete rule for this group?',
837
+ 'wa.groups.no.config': 'Not configured',
838
+ 'wa.groups.allowed': '{count} allowed contacts',
839
+ 'wa.groups.all.allowed': 'All participants allowed',
840
+ 'wa.groups.mention.required': '@ Mention required',
841
+ 'wa.groups.all.messages': 'All messages',
842
+ 'wa.groups.media': 'Process media',
843
+ 'wa.groups.approval': 'Approval before processing',
844
+ 'wa.groups.allowed.contacts': 'Allowed Contacts',
845
+ 'wa.groups.select.all': 'All',
846
+ 'wa.groups.select.none': 'None',
847
+ 'wa.groups.no.selection': 'No selection = everyone can interact',
848
+ 'wa.groups.admin': 'Admin',
849
+ 'wa.approval': 'Approval',
850
+ 'wa.auto': 'Auto',
851
+
852
+ // Terminal
853
+ 'terminal.placeholder': 'Enter command...',
854
+ 'terminal.run': 'Run',
855
+
856
+ // Settings
857
+ 'settings.sudo': 'Sudo / Admin Rights',
858
+ 'settings.sudo.desc': 'Allow Alvin Bot to execute commands with administrator privileges',
859
+ 'settings.sudo.active': 'Active & verified',
860
+ 'settings.sudo.configured': 'Configured, verification needed',
861
+ 'settings.sudo.not.set': 'Not set up',
862
+ 'settings.sudo.status': 'Status',
863
+ 'settings.sudo.storage': 'Storage',
864
+ 'settings.sudo.system': 'System',
865
+ 'settings.sudo.accessibility': 'Accessibility',
866
+ 'settings.sudo.fda': 'Full Disk Access',
867
+ 'settings.sudo.open': 'Open',
868
+ 'settings.sudo.password': 'Enter system password...',
869
+ 'settings.sudo.setup': 'Set up',
870
+ 'settings.sudo.stored.secure': 'Password is stored securely — never in plain text.',
871
+ 'settings.sudo.setup.ok': 'Sudo set up & verified!',
872
+ 'settings.sudo.verify': 'Verify',
873
+ 'settings.sudo.verifying': 'Verifying...',
874
+ 'settings.sudo.verified': 'Sudo works!',
875
+ 'settings.sudo.test': 'Test Command',
876
+ 'settings.sudo.test.prompt': 'Sudo command to test:',
877
+ 'settings.sudo.admin.dialog': 'Admin Dialog',
878
+ 'settings.sudo.admin.reason': 'Reason for admin rights:',
879
+ 'settings.sudo.admin.default.reason': 'Alvin Bot needs administrator rights',
880
+ 'settings.sudo.admin.showing': 'Showing macOS Admin dialog...',
881
+ 'settings.sudo.admin.confirmed': 'Confirmed!',
882
+ 'settings.sudo.admin.denied': 'Denied or error',
883
+ 'settings.sudo.revoke': 'Revoke',
884
+ 'settings.sudo.revoke.confirm': 'Really revoke sudo access? Stored password will be deleted.',
885
+ 'settings.sudo.revoked': 'Sudo access revoked',
886
+ 'settings.sudo.executing': 'Executing...',
887
+ 'settings.sudo.output': 'Output',
888
+ 'settings.env': 'Environment Variables',
889
+ 'settings.env.add': 'Add Variable',
890
+ 'settings.env.name.prompt': 'Variable Name (e.g. DISCORD_TOKEN):',
891
+ 'settings.env.value.prompt': 'Value for {key}:',
892
+ 'settings.env.new.prompt': 'New value for {key}:',
893
+ 'settings.env.saved': '{key} saved! Restart needed.',
894
+ 'settings.env.added': '{key} added!',
895
+ 'settings.sysopen': 'System settings opened',
896
+
897
+ // Maintenance
898
+ 'maint.doctor': 'System Doctor',
899
+ 'maint.doctor.errors': '{errors} errors, {warns} warnings',
900
+ 'maint.doctor.check': 'Check',
901
+ 'maint.doctor.fix.all': 'Fix All',
902
+ 'maint.doctor.fix.all.confirm': 'Automatically repair all issues?',
903
+ 'maint.doctor.fixed': '{ok} fixed',
904
+ 'maint.doctor.failed': '{fail} failed',
905
+ 'maint.backup': 'Backup & Restore',
906
+ 'maint.backup.desc': 'Backup and restore Config, Memory, Tools, SOUL.md',
907
+ 'maint.backup.create': 'Create Backup',
908
+ 'maint.backup.creating': 'Creating backup...',
909
+ 'maint.backup.name.prompt': 'Backup name (optional):',
910
+ 'maint.backup.created': 'Backup "{id}" created ({count} files)',
911
+ 'maint.backup.files': 'Files',
912
+ 'maint.backup.files.in': 'Files in {id}',
913
+ 'maint.backup.restore': 'Restore',
914
+ 'maint.backup.restore.confirm': 'Restore backup "{id}"?\n\nCurrent config files will be overwritten!\nBot restart needed after.',
915
+ 'maint.backup.restored': '{count} files restored! Bot restart needed.',
916
+ 'maint.backup.delete.confirm': 'Permanently delete backup "{id}"?',
917
+ 'maint.backup.deleted': 'Deleted',
918
+ 'maint.backup.none': 'No backups yet.',
919
+ 'maint.pm2': 'Process Control (PM2)',
920
+ 'maint.pm2.desc': 'Start, stop and monitor the bot process',
921
+ 'maint.pm2.status': 'Status',
922
+ 'maint.pm2.loading': 'Loading PM2 status...',
923
+ 'maint.pm2.unreachable': 'Unreachable',
924
+ 'maint.pm2.restart': 'Restart',
925
+ 'maint.pm2.restart.confirm': 'Restart bot? Running queries will be aborted.',
926
+ 'maint.pm2.reload': 'Reload',
927
+ 'maint.pm2.stop': 'Stop',
928
+ 'maint.pm2.stop.confirm': 'Really stop bot? The bot will go offline!',
929
+ 'maint.pm2.start': 'Start',
930
+ 'maint.pm2.flush': 'Flush Logs',
931
+ 'maint.pm2.action.ok': 'PM2 {action} successful',
932
+ 'maint.pm2.action.fail': 'PM2 {action} failed',
933
+ 'maint.pm2.lost': 'Connection lost (bot stopped?)',
934
+ 'maint.logs': 'Recent Logs',
935
+ 'maint.logs.desc': 'Last 30 lines of bot output',
936
+ 'maint.logs.refresh': 'Refresh',
937
+ 'maint.logs.load': 'Click "Refresh" to load logs.',
938
+ 'maint.bot.restart': 'Restart Bot',
939
+ 'maint.bot.restart.confirm': 'Really restart bot? Running queries will be aborted.',
940
+ 'maint.bot.restarting': 'Bot is restarting...',
941
+ 'maint.bot.reconnecting': 'Bot should be available shortly...',
942
+
943
+ // Command Palette
944
+ 'cmd.title': 'Command Palette',
945
+ 'cmd.placeholder': 'Search pages, actions...',
946
+ 'cmd.goto': 'Go to',
947
+ 'cmd.actions': 'Actions',
948
+ 'cmd.action.reset': 'Reset chat',
949
+ 'cmd.action.theme': 'Toggle theme',
950
+ 'cmd.action.export': 'Export chat',
951
+ 'cmd.action.lang': 'Switch language',
952
+ 'cmd.no.results': 'No results',
953
+
954
+ // Provider Add
955
+ 'provider.add.title': 'Add Provider',
956
+ 'provider.add.desc': 'Configure and activate a new AI provider.',
957
+ 'provider.add.select': 'Select provider',
958
+ 'provider.add.key': 'API Key',
959
+ 'provider.add.test': 'Test Key',
960
+ 'provider.add.save': 'Save & Activate',
961
+ 'provider.add.chain': 'Add to fallback chain',
962
+
963
+ // Claude SDK
964
+ 'claude.sdk.title': 'Set up Claude SDK',
965
+ 'claude.sdk.checking': 'Checking CLI installation...',
966
+ 'claude.sdk.step1': 'Step 1: Install CLI',
967
+ 'claude.sdk.step1.cmd': 'npm install -g @anthropic-ai/claude-code',
968
+ 'claude.sdk.step2': 'Step 2: Login',
969
+ 'claude.sdk.step2.cmd': 'claude login',
970
+ 'claude.sdk.step3': 'Step 3: Check status',
971
+
972
+ // Setup Wizard
973
+ 'wizard.title': 'Welcome to Alvin Bot!',
974
+ 'wizard.subtitle': 'Your AI assistant will be ready in 3 simple steps.',
975
+ 'wizard.step': 'Step {n} of {total}',
976
+ 'wizard.step1.title': 'Create Telegram Bot',
977
+ 'wizard.step1.desc': 'Create your own bot on Telegram.',
978
+ 'wizard.step1.instruction1': '1. Open Telegram and search for',
979
+ 'wizard.step1.instruction2': '2. Send /newbot and choose a name',
980
+ 'wizard.step1.instruction3': '3. Paste the bot token here',
981
+ 'wizard.step1.token.placeholder': 'Paste bot token (e.g. 123456:ABC-DEF...)',
982
+ 'wizard.step1.token.validate': 'Validate token',
983
+ 'wizard.step1.token.valid': 'Bot found:',
984
+ 'wizard.step1.token.invalid': 'Invalid token',
985
+ 'wizard.step1.userid': 'Your Telegram User ID',
986
+ 'wizard.step1.userid.placeholder': 'Your User ID (e.g. 123456789)',
987
+ 'wizard.step1.userid.help': 'Send a message to @userinfobot to get your ID.',
988
+ 'wizard.step2.title': 'Choose AI Provider',
989
+ 'wizard.step2.desc': 'Choose which AI powers your bot.',
990
+ 'wizard.step2.recommended': 'Recommended',
991
+ 'wizard.step2.free': 'Free',
992
+ 'wizard.step2.premium': 'Premium',
993
+ 'wizard.step2.key.placeholder': 'Enter API key...',
994
+ 'wizard.step3.title': 'Almost done!',
995
+ 'wizard.step3.desc': 'Optional settings — you can change these later.',
996
+ 'wizard.step3.password': 'Web Dashboard Password (optional)',
997
+ 'wizard.step3.password.placeholder': 'Password for this dashboard',
998
+ 'wizard.step3.password.help': 'Protects access to this dashboard. Leave empty = open access.',
999
+ 'wizard.finish': 'Complete Setup',
1000
+ 'wizard.finish.success': 'Setup complete! Bot is restarting...',
1001
+ 'wizard.finish.restart': 'Please restart the bot: pm2 restart alvin-bot',
1002
+ 'wizard.skip': 'Skip',
1003
+ 'wizard.back': 'Back',
1004
+ 'wizard.next': 'Next',
1005
+ },
1006
+ };
1007
+
1008
+ // Current language
1009
+ let _currentLang = localStorage.getItem('lang') || (navigator.language?.startsWith('de') ? 'de' : 'en');
1010
+
1011
+ /**
1012
+ * Get translated string
1013
+ * @param {string} key - Translation key
1014
+ * @param {Object} params - Parameters for interpolation {count: 5} → replaces {count}
1015
+ * @returns {string} Translated string or key if not found
1016
+ */
1017
+ function t(key, params = {}) {
1018
+ let str = STRINGS[_currentLang]?.[key] || STRINGS.en[key] || key;
1019
+ for (const [k, v] of Object.entries(params)) {
1020
+ str = str.replace(new RegExp(`\\{${k}\\}`, 'g'), v);
1021
+ }
1022
+ return str;
1023
+ }
1024
+
1025
+ /**
1026
+ * Get current language
1027
+ */
1028
+ function getLang() {
1029
+ return _currentLang;
1030
+ }
1031
+
1032
+ /**
1033
+ * Set language and refresh UI
1034
+ * @param {string} lang - 'de' or 'en'
1035
+ */
1036
+ function setLang(lang) {
1037
+ _currentLang = lang;
1038
+ localStorage.setItem('lang', lang);
1039
+ // Re-render the entire UI by re-triggering the active page
1040
+ if (typeof refreshUI === 'function') refreshUI();
1041
+ }
1042
+
1043
+ /**
1044
+ * Toggle between DE and EN
1045
+ */
1046
+ function toggleLang() {
1047
+ setLang(_currentLang === 'de' ? 'en' : 'de');
1048
+ }