dsh-oc-tui 0.2.0 → 0.3.0

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 (50) hide show
  1. package/README.md +21 -563
  2. package/bin/mcp-sse-bridge.mjs +499 -499
  3. package/docs/assets/conversation.png +0 -0
  4. package/docs/assets/cover.png +0 -0
  5. package/docs/assets/home.png +0 -0
  6. package/docs/assets/settings.png +0 -0
  7. package/docs/dsh-std-/346/216/245/345/205/245/350/257/264/346/230/216.md +566 -0
  8. package/docs/user-guide.md +616 -0
  9. package/docs//347/224/250/346/210/267/346/211/213/345/206/214.md +607 -593
  10. package/dsh-plugin.json +69 -69
  11. package/lib/boot-block.js +129 -0
  12. package/lib/diagnostics.js +162 -120
  13. package/lib/dsh-version.js +161 -0
  14. package/lib/git-branch.js +157 -157
  15. package/lib/i18n.js +283 -283
  16. package/lib/image.js +2 -1
  17. package/lib/index.js +5183 -4812
  18. package/lib/locales/ar.js +670 -635
  19. package/lib/locales/de.js +639 -604
  20. package/lib/locales/en.js +35 -0
  21. package/lib/locales/es.js +639 -604
  22. package/lib/locales/fr.js +639 -604
  23. package/lib/locales/id.js +641 -606
  24. package/lib/locales/it.js +639 -604
  25. package/lib/locales/ja.js +639 -604
  26. package/lib/locales/ko.js +639 -604
  27. package/lib/locales/nl.js +639 -604
  28. package/lib/locales/pl.js +653 -618
  29. package/lib/locales/pt-BR.js +639 -604
  30. package/lib/locales/ru.js +653 -618
  31. package/lib/locales/tr.js +639 -604
  32. package/lib/locales/vi.js +641 -606
  33. package/lib/locales/zh-CN.js +640 -605
  34. package/lib/locales/zh-TW.js +640 -605
  35. package/lib/markdown.js +101 -27
  36. package/lib/mcp-monitor.js +189 -0
  37. package/lib/mcp-skill.js +93 -93
  38. package/lib/mcp.js +865 -838
  39. package/lib/model-route.js +66 -0
  40. package/lib/providers.js +712 -712
  41. package/lib/screenshot.js +140 -0
  42. package/lib/splash-opencode.js +29 -26
  43. package/lib/startup.js +66 -48
  44. package/lib/term.js +53 -11
  45. package/lib/themes.js +101 -0
  46. package/lib/ui.js +685 -443
  47. package/lib/updates.js +5 -2
  48. package/lib/web-settings.js +52 -21
  49. package/package.json +160 -146
  50. package/skills/mcp-import/SKILL.md +216 -216
package/lib/locales/fr.js CHANGED
@@ -1,607 +1,642 @@
1
- // French catalog. Keys, order and placeholders mirror `en.js`, the source.
2
- export default {
3
- // ---- shared chrome ------------------------------------------------------
4
- 'common.selectBack': 'Enter sélectionner · Esc retour',
5
- 'common.selectConfirmBack': '↑/↓ sélectionner · Enter confirmer · Esc retour',
6
- 'common.selectContinueExit': '↑/↓ sélectionner · Enter continuer · Esc quitter',
7
- 'common.escBack': 'Esc retour',
8
- 'common.escClose': 'Esc fermer',
9
- 'common.escCancel': 'Esc annuler',
10
- 'common.working': 'En cours…',
11
- 'common.pleaseWait': 'patienter',
12
- 'common.on': 'activé',
13
- 'common.off': 'désactivé',
14
- 'common.unavailable': 'indisponible',
15
- 'common.selected': 'sélectionné',
16
- 'common.default': 'par défaut',
17
- 'common.system': 'système',
18
- 'common.installed': '(installé)',
19
- 'common.more': '… {count} de plus',
20
- 'common.moreLines': '… {count} lignes de plus',
21
- 'common.clickExpand': ' · cliquer pour développer',
22
- 'common.clickCollapse': ' · cliquer pour réduire',
23
- 'common.unknown': 'inconnu',
24
- 'common.emptyMessage': '[message vide]',
25
- 'value.queue': "file d'attente",
26
- 'value.steer': 'diriger',
27
- 'value.auto': 'auto',
28
- 'value.local': 'local',
29
- 'value.textOnly': 'texte seul',
30
- 'value.textImage': 'texte + image',
31
-
32
- // ---- title screen -------------------------------------------------------
33
- 'splash.hint': 'Demander n\'importe quoi... "Réparer les tests cassés"',
34
- 'splash.shortcutSettings': 'paramètres',
35
- 'splash.shortcutThinking': 'réflexion',
36
- 'splash.shortcutBranches': 'branches',
37
-
38
- // ---- header / sidebar / status row -------------------------------------
39
- // ---- command-line help (dsh --profile tui --help) -----------------------
40
- 'startup.description': "Lance l'interface terminal de DeepSeek Harness.",
41
- 'startup.helpOption': 'afficher cette aide',
42
- 'startup.resume': 'reprendre une session persistée existante par id',
43
- 'startup.model': 'id du modèle par défaut des nouvelles sessions',
44
- 'startup.provider': 'route de fournisseur par défaut des nouvelles sessions',
45
- 'startup.sidebar': 'afficher la barre latérale des sessions (par défaut)',
46
- 'startup.noSidebar': 'démarrer sans la barre latérale',
47
- 'startup.examples': 'Exemples :',
48
- 'startup.exampleFresh': 'démarrer une nouvelle session',
49
- 'startup.exampleResume': 'reprendre une session persistée',
50
-
51
- 'header.workspace': 'ESPACE DE TRAVAIL',
52
- 'sidebar.sessions': 'SESSIONS',
53
- 'sidebar.recent': 'RÉCENT',
54
- 'sidebar.newSession': '+ Nouvelle session',
55
- 'status.model': 'modèle',
56
- 'status.draftTokens': '{count} tok brouillon',
57
- 'status.ctrlP': 'ctrl+p commandes',
58
- 'status.interrupt': 'interrompre : ctrl+c',
59
-
60
- // ---- composer command hints --------------------------------------------
61
- 'hint.help': 'afficher l\'aide',
62
- 'hint.settings': 'ouvrir les paramètres',
63
- 'hint.new': 'nouvelle session',
64
- 'hint.resume': 'reprendre une session',
65
- 'hint.model': 'choisir le modèle',
66
- 'hint.provider': 'choisir le fournisseur',
67
- 'hint.rewind': 'retour en arrière',
68
- 'hint.branch': 'changer de branche git',
69
- 'hint.stats': 'stats de session et consommation de tokens',
70
- 'hint.clear': 'vider la vue',
71
- 'hint.cancel': 'annuler le tour en cours',
72
- 'hint.quit': 'quitter',
73
- 'hint.compact': 'compacter le contexte',
74
- 'hint.goal': 'gérer l\'objectif',
75
-
76
- // ---- transcript blocks --------------------------------------------------
77
- 'transcript.turns.one': '{count} tour',
78
- 'transcript.turns.other': '{count} tours',
79
- 'transcript.steps.one': '{count} étape',
80
- 'transcript.steps.other': '{count} étapes',
81
- 'transcript.thinking': ' réflexion',
82
- 'transcript.streaming': ' · en streaming…',
83
- 'transcript.steeringBadge': ' ⟲ intervention',
84
- 'transcript.tasks': 'tâches',
85
- 'transcript.systemPrompt': ' prompt système',
86
- 'transcript.pendingInput': ' entrée en attente · ',
87
- 'transcript.steering': ' intervention',
88
- 'transcript.queued': ' en file',
89
- 'note.systemReminder': 'system-reminder',
90
- 'note.compaction': 'compaction',
91
-
92
- // ---- images and mermaid -------------------------------------------------
93
- 'image.attachment': '🖼 pièce jointe image',
94
- 'image.rendering': '⏳ rendu de l\'image…',
95
- 'image.renderFailed': '⚠ échec du rendu de l\'image · {error}',
96
- 'image.mermaidRendering': '⏳ rendu du diagramme mermaid…',
97
- 'image.mermaidTooWide': '↔ le diagramme mermaid nécessite {width} colonnes, ce volet en a {budget}',
98
- 'image.altFallback': 'image',
99
-
100
- // ---- composer / approval prompt ----------------------------------------
101
- 'composer.imageHint': 'Image collée : utiliser un modèle/plugin multimodal ou deepseek-v4-flash-vision-exp, sinon l\'image ne peut pas être lue',
102
- 'composer.approval': 'Approbation · ',
103
- 'composer.summary': 'Résumé · ',
104
- 'composer.origin': 'Origine · ',
105
- 'composer.risk': 'Risque · ',
106
- 'composer.approvalHint': 'y autoriser · n refuser · Esc annuler',
107
- 'risk.low': 'faible',
108
- 'risk.medium': 'moyen',
109
- 'risk.high': 'élevé',
110
- 'composer.effortHint': 'Tab / ←/→ ajuster · Esc fermer',
111
-
112
- // ---- right status rail --------------------------------------------------
113
- 'rail.model': 'MODÈLE',
114
- 'rail.thinking': 'RÉFLEXION',
115
- 'rail.context': 'CONTEXTE',
116
- 'rail.session': 'SESSION',
117
- 'rail.goal': 'OBJECTIF',
118
- 'rail.subagents': 'SOUS-AGENTS',
119
- 'rail.noData': '—',
120
- 'rail.percentUsed': '{percent} % utilisé',
121
- 'rail.tokens': '~{used} / {window} tokens',
122
- 'rail.cacheHit': 'cache {percent} % de hits',
123
- 'rail.breakdown': 'système {system} · outils {tools} · messages {messages}',
124
- 'rail.contextPending': 'affiché dès que l\'usage est signalé',
125
- 'rail.subagentCounts': '{running} actifs · {total} au total',
126
- 'rail.unreadable': '{label} (illisible)',
127
- 'rail.more': '… +{count} de plus',
128
- 'rail.round': ' · tour {started}/{max}',
129
- 'goal.active': 'actif',
130
- 'goal.paused': 'en pause',
131
- 'goal.blocked': 'bloqué',
132
- 'goal.complete': 'terminé',
133
-
134
- // ---- session stats window ----------------------------------------------
135
- 'stats.title': 'stats de session',
136
- 'stats.hint': 'cliquer sur la bande ou /stats',
137
- 'stats.usage': 'usage',
138
- 'stats.duration': 'durée',
139
- 'stats.speed': 'vitesse',
140
- 'stats.tokens': 'tokens',
141
- 'stats.cache': 'cache',
142
- 'stats.context': 'contexte',
143
- 'stats.noSteps': 'aucune étape terminée pour l\'instant',
144
- 'stats.llmTime': 'LLM {value}',
145
- 'stats.toolTime': 'outils {value}',
146
- 'stats.ttft': 'TTFT moy. {value}',
147
- 'stats.tokensPerSecond': '{value} tok/s',
148
- 'stats.cacheRate': 'cache {percent}%',
149
- 'stats.inOut': 'entrée {input} · sortie {output}',
150
- 'stats.cacheDetail': '{percent} % de hits · lus {read} · écrits {write} · manqués {miss}',
151
- 'stats.contextUsed': 'utilisé {percent} % ~{used} / {window}',
152
- 'stats.systemPrompt': 'prompt système',
153
- 'stats.tools': 'outils',
154
- 'stats.messages': 'messages',
155
- 'stats.compositionUnavailable': 'composition indisponible',
156
- 'stats.contextPending': 'l\'occupation du contexte apparaît dès qu\'une requête signale son usage',
157
-
158
- // ---- questions modal ----------------------------------------------------
159
- 'questions.title': 'Question',
160
- 'questions.titleOf': 'Question {index} sur {total}',
161
- 'questions.defer': 'Esc plus tard',
162
- 'questions.range': '{from}-{to} sur {total} PgUp/PgDn',
163
- 'questions.other': 'Autre : ',
164
- 'questions.answer': 'Réponse : ',
165
- 'questions.placeholder': 'saisir une réponse personnalisée',
166
- 'questions.hintCustom': 'Enter confirmer · Esc retour',
167
- 'questions.hintMulti': 'Espace basculer · Enter continuer · Haut/Bas déplacer',
168
- 'questions.hintSingle': 'Enter sélectionner · Haut/Bas déplacer',
169
-
170
- // ---- secret prompt ------------------------------------------------------
171
- 'secret.hint': 'Enter valider · Esc annuler',
172
-
173
- // ---- settings dialog chrome --------------------------------------------
174
- 'settings.title': 'Paramètres',
175
- 'settings.menu': 'MENU',
176
- 'settings.shared': 'Partagé avec DeepSeek Harness WebUI',
177
- 'settings.footerEdit': 'Enter enregistrer · Esc annuler',
178
- 'settings.footerMenu': '↑/↓ déplacer · Tab menu · Enter sélectionner · Esc retour',
179
- 'settings.footerPlain': '↑/↓ déplacer · Enter sélectionner · Esc retour',
180
- 'settings.confirmHint': '{text} · Y / N',
181
- 'settings.confirmDefault': 'Y confirmer · N annuler',
182
- 'settings.confirmDeleteSession': 'Ctrl+D encore pour supprimer',
183
- 'settings.confirmChange': 'Confirmer cette modification ?',
184
- 'settings.deleteTwice': 'Appuyer à nouveau sur Ctrl+D pour supprimer ',
185
- 'settings.deleteMcpTwice': 'Appuyer à nouveau sur Suppr pour retirer ',
186
- 'settings.noSession': 'aucune session sélectionnée',
187
- 'settings.noSessions': 'aucune session disponible',
188
- 'settings.noMcp': 'aucun serveur MCP sélectionné',
189
- 'settings.noOptions': 'aucune option disponible pour {label}',
190
- 'settings.saved': 'enregistré dans les paramètres DSH',
191
- 'settings.providerRemoved': 'fournisseur retiré',
192
- 'settings.conflict': 'paramètres modifiés ailleurs ; rechargés',
193
- 'settings.error': 'paramètres : {error}',
194
- 'settings.dshSettings': 'Paramètres DSH',
195
- 'settings.optionList': 'Enter sélectionner · Esc retour',
196
-
197
- // ---- settings left menu -------------------------------------------------
198
- 'menu.main': 'Principal',
199
- 'menu.model': 'Modèle',
200
- 'menu.update': 'Mise à jour',
201
- 'menu.mcp': 'MCP',
202
-
203
- // ---- settings rows: main tab -------------------------------------------
204
- 'settings.general': 'Général',
205
- 'settings.graphics': 'Graphismes',
206
- 'settings.sessions': 'Sessions',
207
- 'settings.system': 'Système',
208
- 'settings.busyEnter': 'Enter si occupé',
209
- 'settings.defaultPreset': 'Préréglage par défaut',
210
- 'settings.permissionPreset': 'Préréglage de permissions',
211
- 'settings.permissionDangerConfirm': 'Activer l\'accès illimité aux outils et aux fichiers ?',
212
- 'settings.graphicsRendering': 'Rendu graphique',
213
- 'settings.noProtocolFallback': 'Repli sans protocole',
214
- 'settings.imageHeightCap': 'Hauteur max. d\'image (lignes)',
215
- 'settings.mermaidRendering': 'Rendu Mermaid',
216
- 'settings.newSession': 'Nouvelle session',
217
- 'settings.manageSessions': 'Gérer les sessions',
218
- 'settings.providerConfig': 'Config API du fournisseur',
219
- 'settings.updateManager': 'Gestion des mises à jour',
220
- 'settings.settingsFile': 'Fichier de paramètres',
221
- 'settings.language': 'Langue',
222
- 'settings.languageSystem': 'Système ({language})',
223
- 'settings.languageSaved': 'langue : {language}',
224
-
225
- // ---- model tab ----------------------------------------------------------
226
- 'model.title': 'Modèle',
227
- 'model.subtitle': 'Enter définit un modèle listé par défaut',
228
- 'model.defaultSection': 'Par défaut',
229
- 'model.defaultProvider': 'Fournisseur par défaut',
230
- 'model.defaultModel': 'Modèle par défaut',
231
- 'model.reasoning': 'Raisonnement',
232
- 'model.providerUrl': 'URL du fournisseur',
233
- 'model.providerApiKey': 'Clé API du fournisseur',
234
- 'model.displayName': 'Nom affiché',
235
- 'model.wireProtocol': 'Protocole de transport',
236
- 'model.defaultImageInput': 'Entrée image par défaut',
237
- 'model.models': 'Modèles',
238
- 'model.fetch': 'récupérer…',
239
- 'model.selectedCount': '{count} sélectionnés',
240
- 'model.removeProvider': 'Retirer le fournisseur',
241
- 'model.removeProviderConfirm': 'Retirer {name} et son identifiant géré ?',
242
- 'model.noModels': 'aucun modèle disponible',
243
- 'model.noModelsReturned': 'le fournisseur n\'a renvoyé aucun modèle',
244
- 'model.fetchUnavailable': 'récupération auto indisponible — modèles enregistrés · Enter basculer',
245
- 'model.fetchOk': 'récupéré automatiquement · Enter basculer · Esc retour',
246
- 'model.fetching': 'Récupération des modèles…',
247
- 'model.autoFetching': 'récupération auto…',
248
- 'model.credentialConfigured': 'configuré ({source})',
249
- 'model.credentialMissing': 'non configuré',
250
- 'model.defaultTag': 'par défaut',
251
- 'model.providerUnavailable': 'le fournisseur n\'est plus disponible',
252
- 'model.namespaceUnavailable': 'l\'espace de noms des paramètres du fournisseur est indisponible',
253
- 'model.apiKeyEmpty': 'la clé API ne peut pas être vide',
254
- 'model.credentialsUnavailable': 'le service d\'identifiants est indisponible',
255
- 'model.noProviderModels': 'le fournisseur sélectionné n\'a aucun modèle disponible',
256
- 'model.addCount.one': '{count} disponible',
257
- 'model.addCount.other': '{count} disponibles',
258
-
259
- // ---- add-provider flow --------------------------------------------------
260
- 'provider.add': 'Ajouter un fournisseur',
261
- 'provider.empty': 'aucun fournisseur configuré',
262
- 'provider.pickSubtitle': 'Entrée choisir · Échap retour',
263
- 'provider.catalog': 'Fournisseurs installés',
264
- 'provider.catalogEmpty': 'tous les fournisseurs installés sont déjà configurés',
265
- 'provider.custom': 'API personnalisée — déclarer un point de terminaison',
266
- 'provider.form.catalog': 'Adopter un fournisseur installé',
267
- 'provider.form.custom': 'Déclarer un fournisseur personnalisé',
268
- 'provider.formSubtitle': 'Entrée modifier · Échap retour',
269
- 'provider.field.route': 'ID de route',
270
- 'provider.field.addModel': 'Ajouter un ID de modèle',
271
- 'provider.field.save': 'Enregistrer le fournisseur',
272
- 'provider.hint.route': 'minuscules, chiffres et tirets · clé stockée sous {ref}',
273
- 'provider.error.route': 'ID de route : doit commencer par une lettre et n utiliser que minuscules, chiffres et tirets',
274
- 'provider.error.routeNeeded': 'choisissez un fournisseur',
275
- 'provider.error.taken': 'un fournisseur utilise déjà cet ID de route',
276
- 'provider.error.baseUrl': 'le point de terminaison doit être une URL http ou https',
277
- 'provider.error.baseUrlNeeded': 'un fournisseur personnalisé exige un point de terminaison',
278
- 'provider.error.apiNeeded': 'choisissez le protocole parlé par ce point de terminaison',
279
- 'provider.error.modelsNeeded': 'un fournisseur personnalisé exige au moins un modèle',
280
- 'provider.error.modelId': 'le modèle {index} exige un ID',
281
- 'provider.error.modelDuplicate': 'le modèle "{id}" est listé deux fois',
282
- 'provider.added': 'fournisseur ajouté',
283
- 'provider.accountManaged': 'connecté avec votre compte DeepSeek',
284
- 'provider.search': 'Rechercher',
285
- 'provider.searchPlaceholder': 'tapez pour filtrer',
286
- 'provider.searchEmpty': 'aucun fournisseur ne correspond à "{query}"',
287
-
288
- // ---- une entrée de modèle ------------------------------------------------
289
- 'model.edit': 'Modifier le modèle',
290
- 'model.editHint': 'e modifier · Suppr retirer',
291
- 'model.refresh': 'Actualiser le catalogue',
292
- 'model.selectAll': 'Tout sélectionner',
293
- 'model.fetchRefused': 'le point de terminaison n a renvoyé aucune liste de modèles',
294
- 'model.notSaved': 'ce modèle n est pas encore enregistré',
295
- 'model.removed': 'modèle retiré',
296
- 'model.form.add': 'Ajouter un modèle',
297
- 'model.form.edit': 'Modèle · {id}',
298
- 'model.form.save': 'Enregistrer le modèle',
299
- 'model.form.remove': 'Retirer du fournisseur',
300
- 'model.form.removeConfirm': 'Retirer ce modèle du fournisseur ?',
301
- 'model.field.id': 'ID du modèle',
302
- 'model.field.name': 'Nom affiché',
303
- 'model.field.contextWindow': 'Fenêtre de contexte',
304
- 'model.field.maxTokens': 'Tokens de sortie max',
305
- 'model.field.input': 'Entrée',
306
- 'model.error.idNeeded': 'un modèle a besoin d un ID',
307
- 'model.error.idDuplicate': 'le modèle "{id}" est déjà listé',
308
- 'model.error.capacity': 'fenêtre de contexte et tokens max doivent être des entiers (256K, 1M)',
309
-
310
- // ---- MCP tab ------------------------------------------------------------
311
- 'mcp.title': 'MCP',
312
- 'mcp.subtitle': 'Enter modifier · Suppr retirer · Esc retour',
313
- 'mcp.editSubtitle': 'Enter modifier · Esc retour',
314
- 'mcp.servers': 'Serveurs MCP',
315
- 'mcp.empty': 'Aucun serveur MCP configuré',
316
- 'mcp.add': 'Ajouter un serveur MCP',
317
- 'mcp.scope': 'portée',
318
- 'mcp.scopeUserPrefix': 'utilisateur · {path}',
319
- 'mcp.scopePathPrefix': 'chemin · {path}',
320
- 'mcp.configFiles': 'Fichiers de configuration',
321
- 'mcp.userScope': 'utilisateur (toutes les sessions)',
322
- 'mcp.secrets': 'Secrets',
323
- 'mcp.secretsPlain': 'en clair dans les fichiers de configuration',
324
- 'mcp.loaded': 'chargé',
325
- 'mcp.notCreated': 'pas encore créé',
326
- 'mcp.type.stdio': 'Commande locale',
327
- 'mcp.type.http': 'HTTP',
328
- 'mcp.type.sse': 'SSE',
329
- 'mcp.state.connected': '● connecté',
330
- 'mcp.state.tools.one': '● {count} outil',
331
- 'mcp.state.tools.other': '● {count} outils',
332
- 'mcp.state.pending': '… connexion',
333
- 'mcp.state.disabled': '○ désactivé',
334
- 'mcp.state.idle': '○ non connecté',
335
- 'mcp.form.add': 'Ajouter un serveur MCP',
336
- 'mcp.form.edit': 'Modifier le serveur MCP · {name}',
337
- 'mcp.titleAdd': 'MCP · ajouter',
338
- 'mcp.titleEdit': 'MCP · modifier',
339
- 'mcp.field.name': 'Nom',
340
- 'mcp.field.type': 'Type',
341
- 'mcp.field.timeout': 'Délai (ms)',
342
- 'mcp.field.command': 'Commande',
343
- 'mcp.field.args': 'Arguments',
344
- 'mcp.field.env': 'Environnement (JSON)',
345
- 'mcp.field.url': 'URL',
346
- 'mcp.field.headers': 'En-têtes (JSON)',
347
- 'mcp.field.scope': 'Portée',
348
- 'mcp.field.path': 'Chemin',
349
- 'mcp.field.enabled': 'Activé',
350
- 'mcp.field.save': 'Enregistrer',
351
- 'mcp.field.remove': 'Retirer',
352
- 'mcp.choice.stdio': 'Commande locale (stdio)',
353
- 'mcp.choice.http': 'HTTP (streamable)',
354
- 'mcp.choice.sse': 'SSE (HTTP+SSE hérité)',
355
- 'mcp.choice.scopeUser': 'Utilisateur — toutes les sessions',
356
- 'mcp.choice.scopePath': 'Chemin — sessions sous un répertoire',
357
- 'mcp.removeConfirm': 'Retirer ce serveur MCP et le déconnecter ?',
358
- 'mcp.saved': 'Serveur MCP enregistré',
359
- 'mcp.added': 'Serveur MCP ajouté',
360
- 'mcp.removed': 'Serveur MCP retiré',
361
- 'mcp.error.name': 'le nom doit comporter 1 à 32 lettres, chiffres, "-" ou "_"',
362
- 'mcp.error.duplicate': 'un serveur MCP nommé "{name}" est déjà configuré',
363
- 'mcp.error.timeout': 'timeoutMs doit être un entier entre 1 et {max}',
364
- 'mcp.error.pathNeeded': 'un serveur de portée chemin nécessite un répertoire',
365
- 'mcp.error.pathAbsolute': 'la portée chemin doit être un répertoire absolu',
366
- 'mcp.error.commandNeeded': 'un serveur stdio nécessite une commande',
367
- 'mcp.error.urlParse': 'l\'URL ne peut pas être analysée',
368
- 'mcp.error.urlScheme': 'l\'URL doit utiliser http ou https',
369
- 'mcp.error.pathNotDir': 'la portée chemin n\'est pas un répertoire : {path}',
370
- 'mcp.error.configIsDir': 'le chemin du fichier de configuration est un répertoire : {path}',
371
- 'mcp.error.notFound': 'aucun serveur MCP nommé "{name}" n\'est configuré',
372
- 'mcp.error.documentGone': 'le document définissant "{name}" a disparu : {error}',
373
- 'mcp.error.noClient': 'l\'hôte ne fournit aucun client MCP',
374
- 'mcp.error.connectTimeout': 'la connexion à {name} a expiré',
375
- 'mcp.error.json': 'le document n\'est pas un JSON valide : {error}',
376
- 'mcp.error.jsonObject': 'le document doit être un objet JSON',
377
- 'mcp.error.serversObject': '"servers" doit être un objet JSON',
378
- 'mcp.error.argsArray': 'les arguments doivent être un tableau JSON de chaînes',
379
- 'mcp.error.argsTypes': 'les arguments doivent être des chaînes ou des nombres',
380
- 'mcp.error.argsUnclosed': 'les arguments contiennent un guillemet non fermé',
381
- 'mcp.error.envObject': '{label} doit être un objet JSON',
382
- 'mcp.error.envValue': 'la valeur "{name}" de {label} doit être une chaîne, un nombre ou un booléen',
383
- 'mcp.error.header': 'en-tête HTTP invalide "{name}"',
384
- 'mcp.error.envName': 'nom d\'environnement invalide "{name}"',
385
-
386
- // ---- rewind -------------------------------------------------------------
387
- 'rewind.title': 'Retour en arrière',
388
- 'rewind.restoreTo': 'Restaurer au point précédant : {label}',
389
- 'rewind.restorePrompt': 'Restaurer la conversation au point précédant…',
390
- 'rewind.empty': 'Rien à restaurer pour l\'instant.',
391
- 'rewind.option.conversation': 'Restaurer la conversation',
392
- 'rewind.option.both': 'Restaurer la conversation et les fichiers',
393
- 'rewind.option.code': 'Restaurer les fichiers',
394
- 'rewind.option.cancel': 'Annuler',
395
- 'rewind.current': '(actuel)',
396
- 'rewind.noPoints': 'aucun message utilisateur pour revenir en arrière',
397
- 'rewind.unknownPoint': 'point de retour inconnu "{selector}" — utiliser un nombre ou last',
398
- 'rewind.noPoint': 'aucun point de retour {n} — 1..{count}',
399
- 'rewind.notGit': 'pas un worktree git',
400
- 'rewind.noBackup': 'aucun emplacement de sauvegarde',
401
- 'rewind.filesNotRestored': 'fichiers non restaurés',
402
- 'rewind.filesNotRestoredReason': 'fichiers non restaurés ({reason})',
403
- 'rewind.restored.one': '{count} fichier suivi restauré depuis HEAD',
404
- 'rewind.restored.other': '{count} fichiers suivis restaurés depuis HEAD',
405
- 'rewind.removed.one': '{count} nouveau fichier supprimé',
406
- 'rewind.removed.other': '{count} nouveaux fichiers supprimés',
407
- 'rewind.skipped': '{count} ignorés',
408
- 'rewind.previousSaved': 'contenu précédent enregistré dans {path}',
409
- 'rewind.noChanges': 'aucune modification de fichier après ce point',
410
- 'rewind.image': '[image]',
411
- 'rewind.images': '[{count} images]',
412
- 'rewind.emptyMessage': '(vide)',
413
- 'git.title': 'Branches Git',
414
- 'git.subtitle': 'Actuelle : {branch} · {path}',
415
- 'git.local': 'Branches locales',
416
- 'git.remote': 'Branches distantes',
417
- 'git.empty': 'Aucune branche dans ce dépôt.',
418
- 'git.detached': '(détachée)',
419
- 'git.switched': 'Bascule vers la branche {branch}',
420
- 'git.switchFailed': 'Impossible de basculer vers {branch} : {error}',
421
- 'git.pullDone': 'Mises à jour récupérées',
422
- 'git.pullFailed': 'Impossible de récupérer les mises à jour : {error}',
423
- 'git.listFailed': 'Impossible de lister les branches : {error}',
424
- 'git.notRepo': 'pas une copie de travail git',
425
- 'git.gitMissing': 'git n\'est pas disponible dans le PATH',
426
- 'git.timedOut': 'git a dépassé le délai',
427
- 'git.onlyTitleScreen': 'Le changement de branche n\'est disponible que sur la page vide — quitte la session avec /new',
428
- 'git.footer': '↑/↓ choisir · Entrée basculer · P pull · R actualiser · Échap fermer',
429
-
430
- // ---- update tab ---------------------------------------------------------
431
- 'update.title': 'Mise à jour',
432
- 'update.checking': 'Vérification des versions…',
433
- 'update.fetching': 'récupération depuis le registre npm…',
434
- 'update.fetchingVersions': 'Récupération des versions…',
435
- 'update.versionsSubtitle': 'Enter télécharger · Esc retour',
436
- 'update.installed': 'Installé',
437
- 'update.latest': 'Dernière (tag npm)',
438
- 'update.status': 'État',
439
- 'update.versions': 'Versions',
440
- 'update.selectVersion': 'Choisir une version…',
441
- 'update.restartApply': 'Redémarrer pour appliquer {version}',
442
- 'update.enterRestart': 'Enter redémarrer',
443
- 'update.discard': 'Supprimer {version} téléchargée',
444
- 'update.actions': 'Actions',
445
- 'update.checkNow': 'Vérifier maintenant',
446
- 'update.checkingShort': 'Vérification…',
447
- 'update.startupCheck': 'Vérification au démarrage',
448
- 'update.profile': 'profil',
449
- 'update.dshPackage': 'dsh (@deepseek-ai/dsh)',
450
- 'update.statusCorrupt': 'Installation endommagée — réinstaller ci-dessous',
451
- 'update.statusError': 'Échec de la vérification du registre : {error}',
452
- 'update.statusAvailable': 'Mise à jour disponible → {version}',
453
- 'update.statusUpToDate': 'À jour',
454
- 'update.statusNoStable': 'Aucune version stable — choisir dans Versions',
455
- 'update.notOnPath': 'introuvable dans le PATH',
456
- 'update.subtitleStaged': '{package} {version} téléchargé — redémarrer pour appliquer',
457
- 'update.subtitleIdle': 'Enter sélectionner · télécharger, puis redémarrer pour appliquer',
458
- 'update.download': 'Télécharger',
459
- 'update.contacting': 'contact du registre…',
460
- 'update.version': 'Version',
461
- 'update.savingTo': 'Enregistrement dans',
462
- 'update.escCancels': 'Esc annule',
463
- 'update.restartApplyQ': 'Redémarrer pour appliquer {label} {version} ? (déjà téléchargé)',
464
- 'update.downloadQ': 'Télécharger {label} {version} et redémarrer pour appliquer ?',
465
- 'update.localSwitch': ' — bascule l\'installation locale vers une version du registre',
466
- 'update.downloaded': 'téléchargé · redémarrer pour appliquer',
467
- 'update.downloadedToast': '{label} {version} téléchargé · à appliquer depuis l\'onglet Mise à jour',
468
- 'update.downloadedConfirm': 'Téléchargé redémarrer pour appliquer {label} {version} ? (y/n)',
469
- 'update.alreadyDownloadedConfirm': 'Déjà téléchargé · redémarrer pour appliquer {label} {version} ? (y/n)',
470
- 'update.downloadCancelled': 'téléchargement annulé',
471
- 'update.downloadFailed': 'échec du téléchargement : {error}',
472
- 'update.stagedGone': 'le téléchargement préparé a disparu — choisir à nouveau la version',
473
- 'update.locks.one': 'impossible d\'appliquer pendant que dsh tourne dans {count} autre processus — le fermer et réessayer',
474
- 'update.locks.other': 'impossible d\'appliquer pendant que dsh tourne dans {count} autres processus — les fermer et réessayer',
475
- 'update.noNpm': 'impossible d\'appliquer : npm est introuvable',
476
- 'update.noDshCli': 'impossible d\'appliquer : la CLI dsh est introuvable',
477
- 'update.installerFailed': 'impossible de lancer l\'installateur — redémarrer dsh pour appliquer {label}',
478
- 'update.applying': 'application de {label} · sortie, redémarrage…',
479
- 'update.stagedDiscarded': 'téléchargement préparé supprimé',
480
- 'update.tagCached': 'en cache',
481
- 'update.tagStaged': 'préparé',
482
- 'update.installFailed': 'Échec de l\'installation (code {code}) — réessayer depuis Versions',
483
- 'update.installFailedRetry': 'ouvrir Mise à jour → dsh-oc-tui → Versions, puis choisir une version à retélécharger',
484
- 'update.installUnreadable': 'l\'installation a signalé un succès mais la version installée est {installed} (attendu {expected}) — réparation : {repair}',
485
- 'update.registryUnreachable': 'registre injoignable : {error}',
486
- 'update.notOnRegistry': '{package} n\'est pas sur le registre',
487
- 'update.registryHttp': 'le registre a renvoyé HTTP {status} pour {package}',
488
- 'update.noTarballUrl': 'la réponse du registre ne contient aucune URL de tarball',
489
- 'update.downloadHttp': 'échec du téléchargement : HTTP {status} pour {url}',
490
- 'update.downloadEmpty': 'échec du téléchargement : corps de réponse vide',
491
- 'update.integrityFailed': 'échec de la vérification d\'intégrité pour {file} — téléchargement supprimé',
492
- 'update.npmMissing': 'npm introuvable dans le PATH',
493
- 'update.npmViewFailed': 'npm view {package} a quitté avec {code}',
494
- 'update.timedOut': '\n(délai dépassé après {ms} ms)',
495
- 'update.noOutput': '(aucune sortie)',
496
-
497
- // ---- commands -----------------------------------------------------------
498
- 'command.settings': 'Ouvrir les pages de paramètres de la TUI',
499
- 'command.help': 'Afficher la référence des touches et commandes de la TUI',
500
- 'command.stats': 'Afficher les stats de tokens et de cache de la session',
501
- 'command.new': 'Démarrer une nouvelle session',
502
- 'command.resume': 'Reprendre une session enregistrée',
503
- 'command.clear': 'Vider le transcript',
504
- 'command.cancel': 'Annuler le tour en cours',
505
- 'command.rewind': 'Ramener la session à un point antérieur',
506
- 'command.branch': 'Changer de branche git sur la page vide',
507
- 'command.quit': 'Quitter la TUI',
508
-
509
- // ---- help overlay -------------------------------------------------------
510
- 'help.title': 'DeepSeek Harness TUI — aide',
511
- 'help.enter': 'Enter',
512
- 'help.enterDesc': 'envoyer le message',
513
- 'help.ctrlEnter': 'Ctrl+Enter',
514
- 'help.ctrlEnterDesc': 'insérer un saut de ligne',
515
- 'help.ctrlC': 'Ctrl+C',
516
- 'help.ctrlCDesc': 'annuler le tour en cours ; appuyer à nouveau pour quitter',
517
- 'help.ctrlP': 'Ctrl+P',
518
- 'help.ctrlPDesc': 'ouvrir les paramètres',
519
- 'help.ctrlE': 'Ctrl+E',
520
- 'help.ctrlEDesc': 'basculer le curseur de réflexion',
521
- 'help.tab': 'Tab',
522
- 'help.tabDesc': 'faire défiler l\'intensité de réflexion',
523
- 'help.ctrlN': 'Ctrl+N',
524
- 'help.ctrlNDesc': 'nouvelle session',
525
- 'help.ctrlG': 'Ctrl+G',
526
- 'help.ctrlGDesc': 'changer de branche git (page vide)',
527
- 'help.ctrlD': 'Ctrl+D',
528
- 'help.ctrlDDesc': 'supprimer la session dans Gérer les sessions (appuyer deux fois)',
529
- 'help.pg': 'PgUp / PgDn',
530
- 'help.pgDesc': 'faire défiler le transcript',
531
- 'help.shiftArrows': 'Shift+↑/↓',
532
- 'help.shiftArrowsDesc': 'faire défiler la barre d\'état (fenêtres larges)',
533
- 'help.upDown': 'Haut / Bas',
534
- 'help.upDownDesc': 'curseur haut/bas ; historique aux extrémités',
535
- 'help.mouse': 'Glisser à la souris',
536
- 'help.mouseDesc': 'sélectionner du texte ; le clic droit copie',
537
- 'help.wheel': 'Molette',
538
- 'help.wheelDesc': 'faire défiler transcript / paramètres',
539
- 'help.escEsc': 'Esc Esc',
540
- 'help.escEscDesc': 'sélecteur de retour en arrière',
541
- 'help.esc': 'Esc',
542
- 'help.escDesc': 'fermer l\'overlay · annuler le tour · vider la saisie',
543
- 'help.commands': 'Commandes :',
544
-
545
- // ---- session manager / toasts ------------------------------------------
546
- 'session.newTitle': 'Nouvelle session',
547
- 'session.noSaved': 'Aucune session enregistrée',
548
- 'session.manageTitle': 'Gérer les sessions',
549
- 'session.manageSubtitle': 'Enter ouvrir · Ctrl+D deux fois pour supprimer · Esc retour',
550
- 'session.loading': 'Chargement des sessions...',
551
- 'session.deleted': 'session {label} supprimée',
552
- 'session.deleteFailed': 'supprimer la session : {error}',
553
- 'session.deleteNotFound': 'le répertoire de session enregistré est introuvable',
554
- 'session.deleteCancelled': 'suppression annulée',
555
- 'session.resumed': 'session {id} reprise',
556
- 'session.started': 'session {id} démarrée',
557
- 'session.openFailed': 'échec de l\'ouverture de la session : {error}',
558
- 'session.forkSummary': '{label} depuis {parent} · {files}',
559
- 'session.forkDropped': ' · {count} entrées en attente héritées ignorées',
560
- 'session.conversationOnly': 'conversation seule',
561
- 'session.rewindLabel': 'retour #{n}',
562
- 'session.files': 'fichiers : {summary}',
563
- 'session.error': 'erreur : {error}',
564
- 'session.interruptFirst': 'annuler d\'abord le tour en cours (/cancel)',
565
- 'session.interruptFirstEsc': 'annuler d\'abord le tour en cours (Esc ou /cancel)',
566
- 'session.startFirst': 'démarrer d\'abord une session',
567
- 'session.noReasoningLevels': 'le modèle actuel n\'expose aucun niveau de raisonnement',
568
- 'session.settingsUnavailable': 'paramètres indisponibles',
569
- 'session.interruptRequested': 'interruption demandée',
570
- 'session.nothingToInterrupt': 'rien à interrompre',
571
- 'session.noSessionRunning': 'aucune session en cours',
572
- 'session.promptCleared': 'saisie vidée',
573
- 'session.exitAgain': 'appuyer à nouveau sur Ctrl+C pour quitter',
574
- 'session.usageResume': 'usage : /resume <sessionId>',
575
- 'session.currentModel': 'modèle actuel : {model}',
576
- 'session.modelSet': 'modèle défini sur {model} (s\'applique à la prochaine requête)',
577
- 'session.currentProvider': 'fournisseur actuel : {provider}',
578
- 'session.providerSet': 'fournisseur défini sur {provider} (s\'applique à la prochaine requête)',
579
- 'session.unknownCommand': 'commande inconnue /{name} — essayer /help',
580
- 'session.queryMissing': 'la requête de session n\'est pas montée dans ce profil',
581
- 'session.listHeader': 'sessions :',
582
- 'session.noPersisted': 'aucune session enregistrée',
583
- 'session.listFailed': 'échec de la liste des sessions : {error}',
584
- 'session.modelNoImages': 'le modèle "{model}" ne prend pas en charge les images',
585
- 'session.imageAttachFailed': 'échec de l\'ajout d\'image : {error}',
586
- 'session.attachmentsUnavailable': 'service de pièces jointes indisponible ; l\'image ne peut pas être lue',
587
- 'session.copied.one': '{count} ligne copiée dans le presse-papiers',
588
- 'session.copied.other': '{count} lignes copiées dans le presse-papiers',
589
- 'session.valueRequired': 'une valeur est requise',
590
- 'session.minChars': 'au moins {count} caractères',
591
- 'session.maxChars': 'au plus {count} caractères',
592
- 'session.answerRequired': 'sélectionner une option ou saisir une réponse',
593
- 'session.typeAnswer': 'saisir une réponse ou appuyer sur Esc',
594
- 'session.updatesAvailable': 'Mises à jour : {list} — Ctrl+P → Mise à jour',
595
- 'session.versionsError': 'versions : {error}',
596
- 'session.mcpError': 'MCP : {error}',
597
- 'session.noClipboard': 'aucun chemin de presse-papiers disponible',
598
- 'session.unsupportedInteraction': 'type d\'interaction non pris en charge : {kind}',
599
-
600
- // ---- tool activity summaries -------------------------------------------
601
- 'tool.run': 'exécuter {command}',
602
- 'tool.askUser': 'demander à l\'utilisateur',
603
- 'tool.askQuestions': 'poser {count} questions',
1
+ // French catalog. Keys, order and placeholders mirror `en.js`, the source.
2
+ export default {
3
+ // ---- shared chrome ------------------------------------------------------
4
+ 'common.selectBack': 'Enter sélectionner · Esc retour',
5
+ 'common.selectConfirmBack': '↑/↓ sélectionner · Enter confirmer · Esc retour',
6
+ 'common.selectContinueExit': '↑/↓ sélectionner · Enter continuer · Esc quitter',
7
+ 'common.escBack': 'Esc retour',
8
+ 'common.escClose': 'Esc fermer',
9
+ 'common.escCancel': 'Esc annuler',
10
+ 'common.working': 'En cours…',
11
+ 'common.pleaseWait': 'patienter',
12
+ 'common.on': 'activé',
13
+ 'common.off': 'désactivé',
14
+ 'common.unavailable': 'indisponible',
15
+ 'common.selected': 'sélectionné',
16
+ 'common.default': 'par défaut',
17
+ 'common.system': 'système',
18
+ 'common.installed': '(installé)',
19
+ 'common.more': '… {count} de plus',
20
+ 'common.moreLines': '… {count} lignes de plus',
21
+ 'common.clickExpand': ' · cliquer pour développer',
22
+ 'common.clickCollapse': ' · cliquer pour réduire',
23
+ 'common.unknown': 'inconnu',
24
+ 'common.emptyMessage': '[message vide]',
25
+ 'value.queue': "file d'attente",
26
+ 'value.steer': 'diriger',
27
+ 'value.auto': 'auto',
28
+ 'value.local': 'local',
29
+ 'value.textOnly': 'texte seul',
30
+ 'value.textImage': 'texte + image',
31
+ 'value.show': 'afficher',
32
+ 'value.hide': 'masquer',
33
+
34
+ // ---- title screen -------------------------------------------------------
35
+ 'splash.hint': 'Demander n\'importe quoi... "Réparer les tests cassés"',
36
+ 'splash.shortcutSettings': 'paramètres',
37
+ 'splash.shortcutThinking': 'réflexion',
38
+ 'splash.shortcutBranches': 'branches',
39
+
40
+ // ---- header / sidebar / status row -------------------------------------
41
+ // ---- command-line help (dsh --profile tui --help) -----------------------
42
+ 'startup.description': "Lance l'interface terminal de DeepSeek Harness.",
43
+ 'startup.helpOption': 'afficher cette aide',
44
+ 'startup.resume': 'reprendre une session persistée existante par id',
45
+ 'startup.model': 'id du modèle par défaut des nouvelles sessions',
46
+ 'startup.provider': 'route de fournisseur par défaut des nouvelles sessions',
47
+ 'startup.sidebar': 'afficher la barre latérale des sessions (par défaut)',
48
+ 'startup.noSidebar': 'démarrer sans la barre latérale',
49
+ 'startup.examples': 'Exemples :',
50
+ 'startup.exampleFresh': 'démarrer une nouvelle session',
51
+ 'startup.exampleResume': 'reprendre une session persistée',
52
+
53
+ 'header.workspace': 'ESPACE DE TRAVAIL',
54
+ 'sidebar.sessions': 'SESSIONS',
55
+ 'sidebar.recent': 'RÉCENT',
56
+ 'sidebar.newSession': '+ Nouvelle session',
57
+ 'status.model': 'modèle',
58
+ 'status.draftTokens': '{count} tok brouillon',
59
+ 'status.ctrlP': 'ctrl+p commandes',
60
+ 'status.interrupt': 'interrompre : ctrl+c',
61
+
62
+ // ---- composer command hints --------------------------------------------
63
+ 'hint.help': 'afficher l\'aide',
64
+ 'hint.settings': 'ouvrir les paramètres',
65
+ 'hint.new': 'nouvelle session',
66
+ 'hint.resume': 'reprendre une session',
67
+ 'hint.model': 'choisir le modèle',
68
+ 'hint.provider': 'choisir le fournisseur',
69
+ 'hint.rewind': 'retour en arrière',
70
+ 'hint.branch': 'changer de branche git',
71
+ 'hint.stats': 'stats de session et consommation de tokens',
72
+ 'hint.clear': 'vider la vue',
73
+ 'hint.cancel': 'annuler le tour en cours',
74
+ 'hint.quit': 'quitter',
75
+ 'hint.compact': 'compacter le contexte',
76
+ 'hint.goal': 'gérer l\'objectif',
77
+
78
+ // ---- transcript blocks --------------------------------------------------
79
+ 'transcript.turns.one': '{count} tour',
80
+ 'transcript.turns.other': '{count} tours',
81
+ 'transcript.steps.one': '{count} étape',
82
+ 'transcript.steps.other': '{count} étapes',
83
+ 'transcript.modelChanged': 'Modèle changé de {from} à {to}',
84
+ 'transcript.thinking': ' réflexion',
85
+ 'transcript.streaming': ' · en streaming…',
86
+ 'transcript.steeringBadge': ' ⟲ intervention',
87
+ 'transcript.tasks': 'tâches',
88
+ 'transcript.systemPrompt': ' prompt système',
89
+ 'transcript.pendingInput': ' entrée en attente · ',
90
+ 'transcript.steering': ' intervention',
91
+ 'transcript.queued': ' en file',
92
+ 'note.systemReminder': 'system-reminder',
93
+ 'note.compaction': 'compaction',
94
+ 'note.runtimeContext': 'contexte d\'exécution',
95
+
96
+ // ---- images and mermaid -------------------------------------------------
97
+ 'image.attachment': '🖼 pièce jointe image',
98
+ 'image.rendering': '⏳ rendu de l\'image…',
99
+ 'image.renderFailed': '⚠ échec du rendu de l\'image · {error}',
100
+ 'image.mermaidRendering': '⏳ rendu du diagramme mermaid…',
101
+ 'image.mermaidTooWide': '↔ le diagramme mermaid nécessite {width} colonnes, ce volet en a {budget}',
102
+ 'image.altFallback': 'image',
103
+
104
+ // ---- composer / approval prompt ----------------------------------------
105
+ 'composer.keys': "Enter envoyer · Ctrl+Enter nouvelle ligne · Ctrl+P réglages",
106
+ 'composer.commandKeys': "↑/↓ choisir · Tab compléter · Esc fermer",
107
+ 'composer.imageHint': 'Image collée : utiliser un modèle/plugin multimodal ou deepseek-v4-flash-vision-exp, sinon l\'image ne peut pas être lue',
108
+ 'composer.approval': 'Approbation · ',
109
+ 'composer.summary': 'Résumé · ',
110
+ 'composer.origin': 'Origine · ',
111
+ 'composer.risk': 'Risque · ',
112
+ 'composer.approvalHint': 'y autoriser · n refuser · Esc annuler',
113
+ 'risk.low': 'faible',
114
+ 'risk.medium': 'moyen',
115
+ 'risk.high': 'élevé',
116
+ 'composer.effortHint': 'Tab / ←/→ ajuster · Esc fermer',
117
+
118
+ // ---- right status rail --------------------------------------------------
119
+ 'rail.model': 'MODÈLE',
120
+ 'rail.thinking': 'RÉFLEXION',
121
+ 'rail.context': 'CONTEXTE',
122
+ 'rail.session': 'SESSION',
123
+ 'rail.goal': 'OBJECTIF',
124
+ 'rail.subagents': 'SOUS-AGENTS',
125
+ 'rail.noData': '—',
126
+ 'rail.percentUsed': '{percent} % utilisé',
127
+ 'rail.tokens': '~{used} / {window} tokens',
128
+ 'rail.cacheHit': 'cache {percent} % de hits',
129
+ 'rail.breakdown': 'système {system} · outils {tools} · messages {messages}',
130
+ 'rail.contextPending': 'affiché dès que l\'usage est signalé',
131
+ 'rail.subagentCounts': '{running} actifs · {total} au total',
132
+ 'rail.unreadable': '{label} (illisible)',
133
+ 'rail.more': '… +{count} de plus',
134
+ 'rail.round': ' · tour {started}/{max}',
135
+ 'goal.active': 'actif',
136
+ 'goal.paused': 'en pause',
137
+ 'goal.blocked': 'bloqué',
138
+ 'goal.complete': 'terminé',
139
+
140
+ // ---- session stats window ----------------------------------------------
141
+ 'stats.title': 'stats de session',
142
+ 'stats.hint': 'cliquer sur la bande ou /stats',
143
+ 'stats.usage': 'usage',
144
+ 'stats.duration': 'durée',
145
+ 'stats.speed': 'vitesse',
146
+ 'stats.tokens': 'tokens',
147
+ 'stats.cache': 'cache',
148
+ 'stats.context': 'contexte',
149
+ 'stats.noSteps': 'aucune étape terminée pour l\'instant',
150
+ 'stats.llmTime': 'LLM {value}',
151
+ 'stats.toolTime': 'outils {value}',
152
+ 'stats.ttft': 'TTFT moy. {value}',
153
+ 'stats.tokensPerSecond': '{value} tok/s',
154
+ 'stats.cacheRate': 'cache {percent}%',
155
+ 'stats.inOut': 'entrée {input} · sortie {output}',
156
+ 'stats.cacheDetail': '{percent} % de hits · lus {read} · écrits {write} · manqués {miss}',
157
+ 'stats.contextUsed': 'utilisé {percent} % ~{used} / {window}',
158
+ 'stats.systemPrompt': 'prompt système',
159
+ 'stats.tools': 'outils',
160
+ 'stats.messages': 'messages',
161
+ 'stats.compositionUnavailable': 'composition indisponible',
162
+ 'stats.contextPending': 'l\'occupation du contexte apparaît dès qu\'une requête signale son usage',
163
+
164
+ // ---- questions modal ----------------------------------------------------
165
+ 'questions.title': 'Question',
166
+ 'questions.titleOf': 'Question {index} sur {total}',
167
+ 'questions.defer': 'Esc plus tard',
168
+ 'questions.range': '{from}-{to} sur {total} PgUp/PgDn',
169
+ 'questions.other': 'Autre : ',
170
+ 'questions.answer': 'Réponse : ',
171
+ 'questions.placeholder': 'saisir une réponse personnalisée',
172
+ 'questions.hintCustom': 'Enter confirmer · Esc retour',
173
+ 'questions.hintMulti': 'Espace basculer · Enter continuer · Haut/Bas déplacer',
174
+ 'questions.hintSingle': 'Enter sélectionner · Haut/Bas déplacer',
175
+
176
+ // ---- secret prompt ------------------------------------------------------
177
+ 'secret.hint': 'Enter valider · Esc annuler',
178
+
179
+ // ---- boot gate: the dsh version this build may run on ----
180
+ 'boot.unsupportedTitle': 'Version de dsh non prise en charge',
181
+ 'boot.unverifiedTitle': 'Version de dsh non vérifiée',
182
+ 'boot.runningLabel': 'dsh en cours',
183
+ 'boot.supportedLabel': 'prise en charge',
184
+ 'boot.recommendedLabel': 'recommandée',
185
+ 'boot.verifiedLabel': 'vérifiée',
186
+ 'boot.unsupportedBody': 'Cette version de dsh-oc-tui ne prend en charge que {range}, et {version} en est exclue. Les sessions ne peuvent pas démarrer tant que dsh n\'est pas dans une version prise en charge.',
187
+ 'boot.unverifiedBody': 'Cette version de dsh-oc-tui a été vérifiée avec {verified}, pas avec {version}. Installez {recommended} pour être sûr que tout fonctionne.',
188
+ 'boot.installHint': 'Installez la version recommandée de dsh, puis relancez ce profil :',
189
+ 'boot.updatePluginHint': 'Si une version plus récente de dsh-oc-tui prend déjà en charge ce dsh, mettez plutôt à jour le plugin :',
190
+ 'boot.exitHint': 'Esc ou Ctrl+C pour quitter',
191
+
192
+ // ---- settings dialog chrome --------------------------------------------
193
+ 'settings.title': 'Paramètres',
194
+ 'settings.menu': 'MENU',
195
+ 'settings.shared': 'Partagé avec DeepSeek Harness WebUI',
196
+ 'settings.footerEdit': 'Enter enregistrer · Esc annuler',
197
+ 'settings.footerMenu': '↑/↓ déplacer · Tab menu · Enter sélectionner · Esc retour',
198
+ 'settings.footerPlain': '↑/↓ déplacer · Enter sélectionner · Esc retour',
199
+ 'settings.confirmHint': '{text} · Y / N',
200
+ 'settings.confirmDefault': 'Y confirmer · N annuler',
201
+ 'settings.confirmDeleteSession': 'Ctrl+D encore pour supprimer',
202
+ 'settings.confirmChange': 'Confirmer cette modification ?',
203
+ 'settings.deleteTwice': 'Appuyer à nouveau sur Ctrl+D pour supprimer ',
204
+ 'settings.deleteMcpTwice': 'Appuyer à nouveau sur Suppr pour retirer ',
205
+ 'settings.noSession': 'aucune session sélectionnée',
206
+ 'settings.noSessions': 'aucune session disponible',
207
+ 'settings.noMcp': 'aucun serveur MCP sélectionné',
208
+ 'settings.noOptions': 'aucune option disponible pour {label}',
209
+ 'settings.saved': 'enregistré dans les paramètres DSH',
210
+ 'settings.providerRemoved': 'fournisseur retiré',
211
+ 'settings.conflict': 'paramètres modifiés ailleurs ; rechargés',
212
+ 'settings.error': 'paramètres : {error}',
213
+ 'settings.dshSettings': 'Paramètres DSH',
214
+ 'settings.optionList': 'Enter sélectionner · Esc retour',
215
+
216
+ // ---- settings left menu -------------------------------------------------
217
+ 'menu.main': 'Principal',
218
+ 'menu.model': 'Modèle',
219
+ 'menu.update': 'Mise à jour',
220
+ 'menu.mcp': 'MCP',
221
+
222
+ // ---- settings rows: main tab -------------------------------------------
223
+ 'settings.general': 'Général',
224
+ 'settings.graphics': 'Graphismes',
225
+ 'settings.sessions': 'Sessions',
226
+ 'settings.system': 'Système',
227
+ 'settings.developer': 'Développeur',
228
+ 'settings.contextDetails': 'Détails du contexte',
229
+ 'settings.busyEnter': 'Enter si occupé',
230
+ 'settings.defaultPreset': 'Préréglage par défaut',
231
+ 'settings.permissionPreset': 'Préréglage de permissions',
232
+ 'settings.permissionDangerConfirm': 'Activer l\'accès illimité aux outils et aux fichiers ?',
233
+ 'settings.graphicsRendering': 'Rendu graphique',
234
+ 'settings.noProtocolFallback': 'Repli sans protocole',
235
+ 'settings.imageHeightCap': 'Hauteur max. d\'image (lignes)',
236
+ 'settings.mermaidRendering': 'Rendu Mermaid',
237
+ 'settings.newSession': 'Nouvelle session',
238
+ 'settings.manageSessions': 'Gérer les sessions',
239
+ 'settings.providerConfig': 'Config API du fournisseur',
240
+ 'settings.updateManager': 'Gestion des mises à jour',
241
+ 'settings.settingsFile': 'Fichier de paramètres',
242
+ 'settings.language': 'Langue',
243
+ 'settings.theme': 'Thème',
244
+ 'theme.deepseek': 'DeepSeek Standard',
245
+ 'theme.github-dark': 'GitHub Dark',
246
+ 'theme.dracula': 'Dracula',
247
+ 'theme.vscode-dark': 'VS Code Dark+',
248
+ 'theme.nord': 'Nord',
249
+ 'settings.languageSystem': 'Système ({language})',
250
+ 'settings.languageSaved': 'langue : {language}',
251
+
252
+ // ---- model tab ----------------------------------------------------------
253
+ 'model.title': 'Modèle',
254
+ 'model.subtitle': 'Enter définit un modèle listé par défaut',
255
+ 'model.defaultSection': 'Par défaut',
256
+ 'model.defaultProvider': 'Fournisseur par défaut',
257
+ 'model.defaultModel': 'Modèle par défaut',
258
+ 'model.reasoning': 'Raisonnement',
259
+ 'model.providerUrl': 'URL du fournisseur',
260
+ 'model.providerApiKey': 'Clé API du fournisseur',
261
+ 'model.displayName': 'Nom affiché',
262
+ 'model.wireProtocol': 'Protocole de transport',
263
+ 'model.defaultImageInput': 'Entrée image par défaut',
264
+ 'model.models': 'Modèles',
265
+ 'model.fetch': 'récupérer…',
266
+ 'model.selectedCount': '{count} sélectionnés',
267
+ 'model.removeProvider': 'Retirer le fournisseur',
268
+ 'model.removeProviderConfirm': 'Retirer {name} et son identifiant géré ?',
269
+ 'model.noModels': 'aucun modèle disponible',
270
+ 'model.noModelsReturned': 'le fournisseur n\'a renvoyé aucun modèle',
271
+ 'model.fetchUnavailable': 'récupération auto indisponible — modèles enregistrés · Enter basculer',
272
+ 'model.fetchOk': 'récupéré automatiquement · Enter basculer · Esc retour',
273
+ 'model.fetching': 'Récupération des modèles…',
274
+ 'model.autoFetching': 'récupération auto…',
275
+ 'model.credentialConfigured': 'configuré ({source})',
276
+ 'model.credentialMissing': 'non configuré',
277
+ 'model.defaultTag': 'par défaut',
278
+ 'model.providerUnavailable': 'le fournisseur n\'est plus disponible',
279
+ 'model.namespaceUnavailable': 'l\'espace de noms des paramètres du fournisseur est indisponible',
280
+ 'model.apiKeyEmpty': 'la clé API ne peut pas être vide',
281
+ 'model.credentialsUnavailable': 'le service d\'identifiants est indisponible',
282
+ 'model.noProviderModels': 'le fournisseur sélectionné n\'a aucun modèle disponible',
283
+ 'model.addCount.one': '{count} disponible',
284
+ 'model.addCount.other': '{count} disponibles',
285
+
286
+ // ---- add-provider flow --------------------------------------------------
287
+ 'provider.add': 'Ajouter un fournisseur',
288
+ 'provider.empty': 'aucun fournisseur configuré',
289
+ 'provider.pickSubtitle': 'Entrée choisir · Échap retour',
290
+ 'provider.catalog': 'Fournisseurs installés',
291
+ 'provider.catalogEmpty': 'tous les fournisseurs installés sont déjà configurés',
292
+ 'provider.custom': 'API personnalisée — déclarer un point de terminaison',
293
+ 'provider.form.catalog': 'Adopter un fournisseur installé',
294
+ 'provider.form.custom': 'Déclarer un fournisseur personnalisé',
295
+ 'provider.formSubtitle': 'Entrée modifier · Échap retour',
296
+ 'provider.field.route': 'ID de route',
297
+ 'provider.field.addModel': 'Ajouter un ID de modèle',
298
+ 'provider.field.save': 'Enregistrer le fournisseur',
299
+ 'provider.hint.route': 'minuscules, chiffres et tirets · clé stockée sous {ref}',
300
+ 'provider.error.route': 'ID de route : doit commencer par une lettre et n utiliser que minuscules, chiffres et tirets',
301
+ 'provider.error.routeNeeded': 'choisissez un fournisseur',
302
+ 'provider.error.taken': 'un fournisseur utilise déjà cet ID de route',
303
+ 'provider.error.baseUrl': 'le point de terminaison doit être une URL http ou https',
304
+ 'provider.error.baseUrlNeeded': 'un fournisseur personnalisé exige un point de terminaison',
305
+ 'provider.error.apiNeeded': 'choisissez le protocole parlé par ce point de terminaison',
306
+ 'provider.error.modelsNeeded': 'un fournisseur personnalisé exige au moins un modèle',
307
+ 'provider.error.modelId': 'le modèle {index} exige un ID',
308
+ 'provider.error.modelDuplicate': 'le modèle "{id}" est listé deux fois',
309
+ 'provider.added': 'fournisseur ajouté',
310
+ 'provider.accountManaged': 'connecté avec votre compte DeepSeek',
311
+ 'provider.search': 'Rechercher',
312
+ 'provider.searchPlaceholder': 'tapez pour filtrer',
313
+ 'provider.searchEmpty': 'aucun fournisseur ne correspond à "{query}"',
314
+
315
+ // ---- une entrée de modèle ------------------------------------------------
316
+ 'model.edit': 'Modifier le modèle',
317
+ 'model.editHint': 'e modifier · Suppr retirer',
318
+ 'model.refresh': 'Actualiser le catalogue',
319
+ 'model.selectAll': 'Tout sélectionner',
320
+ 'model.fetchRefused': 'le point de terminaison n a renvoyé aucune liste de modèles',
321
+ 'model.notSaved': 'ce modèle n est pas encore enregistré',
322
+ 'model.removed': 'modèle retiré',
323
+ 'model.form.add': 'Ajouter un modèle',
324
+ 'model.form.edit': 'Modèle · {id}',
325
+ 'model.form.save': 'Enregistrer le modèle',
326
+ 'model.form.remove': 'Retirer du fournisseur',
327
+ 'model.form.removeConfirm': 'Retirer ce modèle du fournisseur ?',
328
+ 'model.field.id': 'ID du modèle',
329
+ 'model.field.name': 'Nom affiché',
330
+ 'model.field.contextWindow': 'Fenêtre de contexte',
331
+ 'model.field.maxTokens': 'Tokens de sortie max',
332
+ 'model.field.input': 'Entrée',
333
+ 'model.error.idNeeded': 'un modèle a besoin d un ID',
334
+ 'model.error.idDuplicate': 'le modèle "{id}" est déjà listé',
335
+ 'model.error.capacity': 'fenêtre de contexte et tokens max doivent être des entiers (256K, 1M)',
336
+
337
+ // ---- MCP tab ------------------------------------------------------------
338
+ 'mcp.title': 'MCP',
339
+ 'mcp.subtitle': 'Enter modifier · Suppr retirer · Esc retour',
340
+ 'mcp.editSubtitle': 'Enter modifier · Esc retour',
341
+ 'mcp.servers': 'Serveurs MCP',
342
+ 'mcp.empty': 'Aucun serveur MCP configuré',
343
+ 'mcp.add': 'Ajouter un serveur MCP',
344
+ 'mcp.scope': 'portée',
345
+ 'mcp.scopeUserPrefix': 'utilisateur · {path}',
346
+ 'mcp.scopePathPrefix': 'chemin · {path}',
347
+ 'mcp.configFiles': 'Fichiers de configuration',
348
+ 'mcp.userScope': 'utilisateur (toutes les sessions)',
349
+ 'mcp.secrets': 'Secrets',
350
+ 'mcp.secretsPlain': 'en clair dans les fichiers de configuration',
351
+ 'mcp.loaded': 'chargé',
352
+ 'mcp.notCreated': 'pas encore créé',
353
+ 'mcp.type.stdio': 'Commande locale',
354
+ 'mcp.type.http': 'HTTP',
355
+ 'mcp.type.sse': 'SSE',
356
+ 'mcp.state.connected': '● connecté',
357
+ 'mcp.state.tools.one': '● {count} outil',
358
+ 'mcp.state.tools.other': '● {count} outils',
359
+ 'mcp.state.pending': '… connexion',
360
+ 'mcp.state.disabled': '○ désactivé',
361
+ 'mcp.state.idle': '○ non connecté',
362
+ 'mcp.notice.connected': "MCP {name}: connecté",
363
+ 'mcp.notice.failed': "MCP {name}: échec de la connexion",
364
+ 'mcp.form.add': 'Ajouter un serveur MCP',
365
+ 'mcp.form.edit': 'Modifier le serveur MCP · {name}',
366
+ 'mcp.titleAdd': 'MCP · ajouter',
367
+ 'mcp.titleEdit': 'MCP · modifier',
368
+ 'mcp.field.name': 'Nom',
369
+ 'mcp.field.type': 'Type',
370
+ 'mcp.field.timeout': 'Délai (ms)',
371
+ 'mcp.field.command': 'Commande',
372
+ 'mcp.field.args': 'Arguments',
373
+ 'mcp.field.env': 'Environnement (JSON)',
374
+ 'mcp.field.url': 'URL',
375
+ 'mcp.field.headers': 'En-têtes (JSON)',
376
+ 'mcp.field.scope': 'Portée',
377
+ 'mcp.field.path': 'Chemin',
378
+ 'mcp.field.enabled': 'Activé',
379
+ 'mcp.field.save': 'Enregistrer',
380
+ 'mcp.field.remove': 'Retirer',
381
+ 'mcp.choice.stdio': 'Commande locale (stdio)',
382
+ 'mcp.choice.http': 'HTTP (streamable)',
383
+ 'mcp.choice.sse': 'SSE (HTTP+SSE hérité)',
384
+ 'mcp.choice.scopeUser': 'Utilisateur — toutes les sessions',
385
+ 'mcp.choice.scopePath': 'Chemin — sessions sous un répertoire',
386
+ 'mcp.removeConfirm': 'Retirer ce serveur MCP et le déconnecter ?',
387
+ 'mcp.saved': 'Serveur MCP enregistré',
388
+ 'mcp.added': 'Serveur MCP ajouté',
389
+ 'mcp.removed': 'Serveur MCP retiré',
390
+ 'mcp.error.name': 'le nom doit comporter 1 à 32 lettres, chiffres, "-" ou "_"',
391
+ 'mcp.error.duplicate': 'un serveur MCP nommé "{name}" est déjà configuré',
392
+ 'mcp.error.timeout': 'timeoutMs doit être un entier entre 1 et {max}',
393
+ 'mcp.error.pathNeeded': 'un serveur de portée chemin nécessite un répertoire',
394
+ 'mcp.error.pathAbsolute': 'la portée chemin doit être un répertoire absolu',
395
+ 'mcp.error.commandNeeded': 'un serveur stdio nécessite une commande',
396
+ 'mcp.error.urlParse': 'l\'URL ne peut pas être analysée',
397
+ 'mcp.error.urlScheme': 'l\'URL doit utiliser http ou https',
398
+ 'mcp.error.pathNotDir': 'la portée chemin n\'est pas un répertoire : {path}',
399
+ 'mcp.error.configIsDir': 'le chemin du fichier de configuration est un répertoire : {path}',
400
+ 'mcp.error.notFound': 'aucun serveur MCP nommé "{name}" n\'est configuré',
401
+ 'mcp.error.documentGone': 'le document définissant "{name}" a disparu : {error}',
402
+ 'mcp.error.noClient': 'l\'hôte ne fournit aucun client MCP',
403
+ 'mcp.error.connectTimeout': 'la connexion à {name} a expiré',
404
+ 'mcp.error.json': 'le document n\'est pas un JSON valide : {error}',
405
+ 'mcp.error.jsonObject': 'le document doit être un objet JSON',
406
+ 'mcp.error.serversObject': '"servers" doit être un objet JSON',
407
+ 'mcp.error.argsArray': 'les arguments doivent être un tableau JSON de chaînes',
408
+ 'mcp.error.argsTypes': 'les arguments doivent être des chaînes ou des nombres',
409
+ 'mcp.error.argsUnclosed': 'les arguments contiennent un guillemet non fermé',
410
+ 'mcp.error.envObject': '{label} doit être un objet JSON',
411
+ 'mcp.error.envValue': 'la valeur "{name}" de {label} doit être une chaîne, un nombre ou un booléen',
412
+ 'mcp.error.header': 'en-tête HTTP invalide "{name}"',
413
+ 'mcp.error.envName': 'nom d\'environnement invalide "{name}"',
414
+
415
+ // ---- rewind -------------------------------------------------------------
416
+ 'rewind.title': 'Retour en arrière',
417
+ 'rewind.restoreTo': 'Restaurer au point précédant : {label}',
418
+ 'rewind.restorePrompt': 'Restaurer la conversation au point précédant…',
419
+ 'rewind.empty': 'Rien à restaurer pour l\'instant.',
420
+ 'rewind.option.conversation': 'Restaurer la conversation',
421
+ 'rewind.option.both': 'Restaurer la conversation et les fichiers',
422
+ 'rewind.option.code': 'Restaurer les fichiers',
423
+ 'rewind.option.cancel': 'Annuler',
424
+ 'rewind.current': '(actuel)',
425
+ 'rewind.noPoints': 'aucun message utilisateur pour revenir en arrière',
426
+ 'rewind.unknownPoint': 'point de retour inconnu "{selector}" — utiliser un nombre ou last',
427
+ 'rewind.noPoint': 'aucun point de retour {n} — 1..{count}',
428
+ 'rewind.notGit': 'pas un worktree git',
429
+ 'rewind.noBackup': 'aucun emplacement de sauvegarde',
430
+ 'rewind.filesNotRestored': 'fichiers non restaurés',
431
+ 'rewind.filesNotRestoredReason': 'fichiers non restaurés ({reason})',
432
+ 'rewind.restored.one': '{count} fichier suivi restauré depuis HEAD',
433
+ 'rewind.restored.other': '{count} fichiers suivis restaurés depuis HEAD',
434
+ 'rewind.removed.one': '{count} nouveau fichier supprimé',
435
+ 'rewind.removed.other': '{count} nouveaux fichiers supprimés',
436
+ 'rewind.skipped': '{count} ignorés',
437
+ 'rewind.previousSaved': 'contenu précédent enregistré dans {path}',
438
+ 'rewind.noChanges': 'aucune modification de fichier après ce point',
439
+ 'rewind.image': '[image]',
440
+ 'rewind.images': '[{count} images]',
441
+ 'rewind.emptyMessage': '(vide)',
442
+ 'git.title': 'Branches Git',
443
+ 'git.subtitle': 'Actuelle : {branch} · {path}',
444
+ 'git.local': 'Branches locales',
445
+ 'git.remote': 'Branches distantes',
446
+ 'git.empty': 'Aucune branche dans ce dépôt.',
447
+ 'git.detached': '(détachée)',
448
+ 'git.switched': 'Bascule vers la branche {branch}',
449
+ 'git.switchFailed': 'Impossible de basculer vers {branch} : {error}',
450
+ 'git.pullDone': 'Mises à jour récupérées',
451
+ 'git.pullFailed': 'Impossible de récupérer les mises à jour : {error}',
452
+ 'git.listFailed': 'Impossible de lister les branches : {error}',
453
+ 'git.notRepo': 'pas une copie de travail git',
454
+ 'git.gitMissing': 'git n\'est pas disponible dans le PATH',
455
+ 'git.timedOut': 'git a dépassé le délai',
456
+ 'git.onlyTitleScreen': 'Le changement de branche n\'est disponible que sur la page vide — quitte la session avec /new',
457
+ 'git.footer': '↑/↓ choisir · Entrée basculer · P pull · R actualiser · Échap fermer',
458
+
459
+ // ---- update tab ---------------------------------------------------------
460
+ 'update.title': 'Mise à jour',
461
+ 'update.checking': 'Vérification des versions…',
462
+ 'update.fetching': 'récupération depuis le registre npm…',
463
+ 'update.fetchingVersions': 'Récupération des versions…',
464
+ 'update.versionsSubtitle': 'Enter télécharger · Esc retour',
465
+ 'update.installed': 'Installé',
466
+ 'update.latest': 'Dernière (tag npm)',
467
+ 'update.status': 'État',
468
+ 'update.versions': 'Versions',
469
+ 'update.selectVersion': 'Choisir une version…',
470
+ 'update.restartApply': 'Redémarrer pour appliquer {version}',
471
+ 'update.enterRestart': 'Enter redémarrer',
472
+ 'update.discard': 'Supprimer {version} téléchargée',
473
+ 'update.actions': 'Actions',
474
+ 'update.checkNow': 'Vérifier maintenant',
475
+ 'update.checkingShort': 'Vérification…',
476
+ 'update.startupCheck': 'Vérification au démarrage',
477
+ 'update.profile': 'profil',
478
+ 'update.dshPackage': 'dsh (@deepseek-ai/dsh)',
479
+ 'update.statusCorrupt': 'Installation endommagée — réinstaller ci-dessous',
480
+ 'update.statusError': 'Échec de la vérification du registre : {error}',
481
+ 'update.statusAvailable': 'Mise à jour disponible → {version}',
482
+ 'update.statusUpToDate': 'À jour',
483
+ 'update.statusNoStable': 'Aucune version stable — choisir dans Versions',
484
+ 'update.notOnPath': 'introuvable dans le PATH',
485
+ 'update.subtitleStaged': '{package} {version} téléchargé — redémarrer pour appliquer',
486
+ 'update.subtitleIdle': 'Enter sélectionner · télécharger, puis redémarrer pour appliquer',
487
+ 'update.download': 'Télécharger',
488
+ 'update.contacting': 'contact du registre…',
489
+ 'update.version': 'Version',
490
+ 'update.savingTo': 'Enregistrement dans',
491
+ 'update.escCancels': 'Esc annule',
492
+ 'update.restartApplyQ': 'Redémarrer pour appliquer {label} {version} ? (déjà téléchargé)',
493
+ 'update.downloadQ': 'Télécharger {label} {version} et redémarrer pour appliquer ?',
494
+ 'update.localSwitch': ' — bascule l\'installation locale vers une version du registre',
495
+ 'update.downloaded': 'téléchargé · redémarrer pour appliquer',
496
+ 'update.downloadedToast': '{label} {version} téléchargé · à appliquer depuis l\'onglet Mise à jour',
497
+ 'update.downloadedConfirm': 'Téléchargé redémarrer pour appliquer {label} {version} ? (y/n)',
498
+ 'update.alreadyDownloadedConfirm': 'Déjà téléchargé · redémarrer pour appliquer {label} {version} ? (y/n)',
499
+ 'update.downloadCancelled': 'téléchargement annulé',
500
+ 'update.downloadFailed': 'échec du téléchargement : {error}',
501
+ 'update.stagedGone': 'le téléchargement préparé a disparu — choisir à nouveau la version',
502
+ 'update.locks.one': 'impossible d\'appliquer pendant que dsh tourne dans {count} autre processus — le fermer et réessayer',
503
+ 'update.locks.other': 'impossible d\'appliquer pendant que dsh tourne dans {count} autres processus — les fermer et réessayer',
504
+ 'update.noNpm': 'impossible d\'appliquer : npm est introuvable',
505
+ 'update.noDshCli': 'impossible d\'appliquer : la CLI dsh est introuvable',
506
+ 'update.installerFailed': 'impossible de lancer l\'installateur — redémarrer dsh pour appliquer {label}',
507
+ 'update.applying': 'application de {label} · sortie, redémarrage…',
508
+ 'update.stagedDiscarded': 'téléchargement préparé supprimé',
509
+ 'update.tagCached': 'en cache',
510
+ 'update.tagStaged': 'préparé',
511
+ 'update.installFailed': 'Échec de l\'installation (code {code}) — réessayer depuis Versions',
512
+ 'update.installFailedRetry': 'ouvrir Mise à jour → dsh-oc-tui → Versions, puis choisir une version à retélécharger',
513
+ 'update.installUnreadable': 'l\'installation a signalé un succès mais la version installée est {installed} (attendu {expected}) — réparation : {repair}',
514
+ 'update.registryUnreachable': 'registre injoignable : {error}',
515
+ 'update.notOnRegistry': '{package} n\'est pas sur le registre',
516
+ 'update.registryHttp': 'le registre a renvoyé HTTP {status} pour {package}',
517
+ 'update.noTarballUrl': 'la réponse du registre ne contient aucune URL de tarball',
518
+ 'update.downloadHttp': 'échec du téléchargement : HTTP {status} pour {url}',
519
+ 'update.downloadEmpty': 'échec du téléchargement : corps de réponse vide',
520
+ 'update.integrityFailed': 'échec de la vérification d\'intégrité pour {file} — téléchargement supprimé',
521
+ 'update.npmMissing': 'npm introuvable dans le PATH',
522
+ 'update.npmViewFailed': 'npm view {package} a quitté avec {code}',
523
+ 'update.timedOut': '\n(délai dépassé après {ms} ms)',
524
+ 'update.noOutput': '(aucune sortie)',
525
+
526
+ // ---- commands -----------------------------------------------------------
527
+ 'command.settings': 'Ouvrir les pages de paramètres de la TUI',
528
+ 'command.help': 'Afficher la référence des touches et commandes de la TUI',
529
+ 'command.stats': 'Afficher les stats de tokens et de cache de la session',
530
+ 'command.new': 'Démarrer une nouvelle session',
531
+ 'command.resume': 'Reprendre une session enregistrée',
532
+ 'command.clear': 'Vider le transcript',
533
+ 'command.cancel': 'Annuler le tour en cours',
534
+ 'command.rewind': 'Ramener la session à un point antérieur',
535
+ 'command.branch': 'Changer de branche git sur la page vide',
536
+ 'command.quit': 'Quitter la TUI',
537
+
538
+ // ---- help overlay -------------------------------------------------------
539
+ 'help.title': 'DeepSeek Harness TUI — aide',
540
+ 'help.enter': 'Enter',
541
+ 'help.enterDesc': 'envoyer le message',
542
+ 'help.ctrlEnter': 'Ctrl+Enter',
543
+ 'help.ctrlEnterDesc': 'insérer un saut de ligne',
544
+ 'help.ctrlC': 'Ctrl+C',
545
+ 'help.ctrlCDesc': 'annuler le tour en cours ; appuyer à nouveau pour quitter',
546
+ 'help.ctrlP': 'Ctrl+P',
547
+ 'help.ctrlPDesc': 'ouvrir les paramètres',
548
+ 'help.ctrlE': 'Ctrl+E',
549
+ 'help.ctrlEDesc': 'basculer le curseur de réflexion',
550
+ 'help.tab': 'Tab',
551
+ 'help.tabDesc': 'faire défiler l\'intensité de réflexion',
552
+ 'help.ctrlN': 'Ctrl+N',
553
+ 'help.ctrlNDesc': 'nouvelle session',
554
+ 'help.ctrlG': 'Ctrl+G',
555
+ 'help.ctrlGDesc': 'changer de branche git (page vide)',
556
+ 'help.ctrlD': 'Ctrl+D',
557
+ 'help.ctrlDDesc': 'supprimer la session dans Gérer les sessions (appuyer deux fois)',
558
+ 'help.pg': 'PgUp / PgDn',
559
+ 'help.pgDesc': 'faire défiler le transcript',
560
+ 'help.shiftArrows': 'Shift+↑/↓',
561
+ 'help.shiftArrowsDesc': 'faire défiler la barre d\'état (fenêtres larges)',
562
+ 'help.upDown': 'Haut / Bas',
563
+ 'help.upDownDesc': 'curseur haut/bas ; historique aux extrémités',
564
+ 'help.mouse': 'Glisser à la souris',
565
+ 'help.mouseDesc': 'sélectionner du texte ; le clic droit copie',
566
+ 'help.wheel': 'Molette',
567
+ 'help.wheelDesc': 'faire défiler transcript / paramètres',
568
+ 'help.escEsc': 'Esc Esc',
569
+ 'help.escEscDesc': 'sélecteur de retour en arrière',
570
+ 'help.esc': 'Esc',
571
+ 'help.escDesc': 'fermer l\'overlay · annuler le tour · vider la saisie',
572
+ 'help.commands': 'Commandes :',
573
+
574
+ // ---- session manager / toasts ------------------------------------------
575
+ 'session.newTitle': 'Nouvelle session',
576
+ 'session.noSaved': 'Aucune session enregistrée',
577
+ 'session.manageTitle': 'Gérer les sessions',
578
+ 'session.manageSubtitle': 'Enter ouvrir · Ctrl+D deux fois pour supprimer · Esc retour',
579
+ 'session.loading': 'Chargement des sessions...',
580
+ 'session.deleted': 'session {label} supprimée',
581
+ 'session.deleteFailed': 'supprimer la session : {error}',
582
+ 'session.deleteNotFound': 'le répertoire de session enregistré est introuvable',
583
+ 'session.deleteCancelled': 'suppression annulée',
584
+ 'session.resumed': 'session {id} reprise',
585
+ 'session.started': 'session {id} démarrée',
586
+ 'session.openFailed': 'échec de l\'ouverture de la session : {error}',
587
+ 'session.forkSummary': '{label} depuis {parent} · {files}',
588
+ 'session.forkDropped': ' · {count} entrées en attente héritées ignorées',
589
+ 'session.conversationOnly': 'conversation seule',
590
+ 'session.rewindLabel': 'retour #{n}',
591
+ 'session.files': 'fichiers : {summary}',
592
+ 'session.error': 'erreur : {error}',
593
+ 'session.interruptFirst': 'annuler d\'abord le tour en cours (/cancel)',
594
+ 'session.interruptFirstEsc': 'annuler d\'abord le tour en cours (Esc ou /cancel)',
595
+ 'session.startFirst': 'démarrer d\'abord une session',
596
+ 'session.noReasoningLevels': 'le modèle actuel n\'expose aucun niveau de raisonnement',
597
+ 'session.settingsUnavailable': 'paramètres indisponibles',
598
+ 'session.interruptRequested': 'interruption demandée',
599
+ 'session.nothingToInterrupt': 'rien à interrompre',
600
+ 'session.noSessionRunning': 'aucune session en cours',
601
+ 'session.promptCleared': 'saisie vidée',
602
+ 'session.exitAgain': 'appuyer à nouveau sur Ctrl+C pour quitter',
603
+ 'session.usageResume': 'usage : /resume <sessionId>',
604
+ 'session.currentModel': 'modèle actuel : {model}',
605
+ 'session.modelSet': 'modèle défini sur {model} (s\'applique à la prochaine requête)',
606
+ 'session.currentProvider': 'fournisseur actuel : {provider}',
607
+ 'session.providerSet': 'fournisseur défini sur {provider} (s\'applique à la prochaine requête)',
608
+ 'session.unknownCommand': 'commande inconnue /{name} — essayer /help',
609
+ 'session.queryMissing': 'la requête de session n\'est pas montée dans ce profil',
610
+ 'session.listHeader': 'sessions :',
611
+ 'session.noPersisted': 'aucune session enregistrée',
612
+ 'session.listFailed': 'échec de la liste des sessions : {error}',
613
+ 'session.modelNoImages': 'le modèle "{model}" ne prend pas en charge les images',
614
+ 'session.imageAttachFailed': 'échec de l\'ajout d\'image : {error}',
615
+ 'session.attachmentsUnavailable': 'service de pièces jointes indisponible ; l\'image ne peut pas être lue',
616
+ 'session.copied.one': '{count} ligne copiée dans le presse-papiers',
617
+ 'session.copied.other': '{count} lignes copiées dans le presse-papiers',
618
+ 'session.valueRequired': 'une valeur est requise',
619
+ 'session.minChars': 'au moins {count} caractères',
620
+ 'session.maxChars': 'au plus {count} caractères',
621
+ 'session.answerRequired': 'sélectionner une option ou saisir une réponse',
622
+ 'session.typeAnswer': 'saisir une réponse ou appuyer sur Esc',
623
+ 'session.updatesAvailable': 'Mises à jour : {list} — Ctrl+P → Mise à jour',
624
+ 'session.versionsError': 'versions : {error}',
625
+ 'session.mcpError': 'MCP : {error}',
626
+ 'session.noClipboard': 'aucun chemin de presse-papiers disponible',
627
+ 'session.unsupportedInteraction': 'type d\'interaction non pris en charge : {kind}',
628
+
629
+ // ---- tool activity summaries -------------------------------------------
630
+ 'tool.run': 'exécuter {command}',
631
+ 'tool.askUser': 'demander à l\'utilisateur',
632
+ 'tool.askQuestions': 'poser {count} questions',
604
633
 
605
634
  // ---- host diagnostics ----------------------------------------------------
606
635
  'diagnostics.notice': 'Diagnostics de l’hôte consignés dans {path}',
607
- }
636
+
637
+ // ---- screenshots --------------------------------------------------------
638
+ "screenshot.shortcut": "Capture d’écran",
639
+ "screenshot.directory": "Dossier des captures",
640
+ "screenshot.saved": "Capture enregistrée",
641
+ "screenshot.failed": "Échec de la capture",
642
+ }