Modèle de données : - migration #11 git_credentials (secrets chiffrés SecretBox : secret_encrypted ; colonnes ssh/oauth posées pour P12b/P12c) ; #12 repos ALTER remote_url/git_service/credential_id (pas de FK) - types partagés api.ts (GitCredentialSummary sans secret + hasSecret/secretLast4, CRUD, RemoteRepoSummary, Clone*) ; protocole additif : topic 'clones' + message clone_update (CloneOperation) Backend : - core/git-credentials.ts (GitCredentialsManager(db, box)) : CRUD chiffré, test() (GET /user), getSecret()/authContext() internes, NULLification de repos.credential_id à la suppression - core/git-clients/ (github/gitlab/gitea) via fetch, sans dépendance : verify()+listRepos() paginés, erreurs typées AUTH_FAILED/RATE_LIMITED/UNREACHABLE, SSRF base_url http(s) - core/git-auth.ts : withGitAuth (GIT_ASKPASS éphémère 0o700, secret par env, GIT_TERMINAL_PROMPT=0, jamais dans l'URL/.git/config, nettoyage finally) - core/git.ts cloneRepo (spawn git clone --progress, parse progression, timeout) - core/clone-manager.ts (EventEmitter) : clone async, dest confiné sous scanRoots + non existant, auto-enregistrement via addRepo + métadonnées de provenance, nettoyage du clone partiel, events topic 'clones' - routes/git-connections.ts (CRUD + /test + /:id/repos + POST /repos/clone 202 + GET /repos/clone/:id) ; app.ts câble box→GitCredentialsManager + CloneManager→gateway ; gateway relaie 'clones' Frontend : - ws-client subscribeClones ; stores git-connections + clone (suivi WS) - components/settings/GitConnectionsSection (liste + formulaire pat/app_password, secret jamais ré-affiché) inséré dans SettingsView ; CloneRepoModal (connexion → repos distants paginés → dest scanRoots[0] → barre de progression WS → redirection) ; bouton « Cloner » dans DashboardView ; i18n EN+FR Tests : git-credentials (round-trip SecretBox, résumé sans secret, NULLification) ; acceptance-p12.mjs (clone bare local file:// → clone_update done + repo enregistré + secret ABSENT de l'API, de la DB et du .git/config) Sous-phases restantes : P12b (SSH), P12c (OAuth device flow).
569 lines
20 KiB
TypeScript
569 lines
20 KiB
TypeScript
import type en from './en';
|
||
|
||
const fr: typeof en = {
|
||
common: {
|
||
appName: 'Arboretum',
|
||
loading: 'Chargement…',
|
||
cancel: 'Annuler',
|
||
logout: 'Se déconnecter',
|
||
language: 'Langue',
|
||
refresh: 'Rafraîchir',
|
||
back: 'Retour',
|
||
search: 'Rechercher',
|
||
settings: 'Réglages',
|
||
close: 'Fermer',
|
||
retry: 'Réessayer',
|
||
confirm: 'Confirmer',
|
||
delete: 'Supprimer',
|
||
},
|
||
login: {
|
||
title: 'Connectez-vous avec votre jeton d’accès',
|
||
tokenLabel: 'Jeton d’accès',
|
||
tokenPlaceholder: 'arb_…',
|
||
submit: 'Se connecter',
|
||
submitting: 'Connexion…',
|
||
invalidToken: 'Jeton invalide',
|
||
rateLimited: 'Trop de tentatives — patientez avant de réessayer',
|
||
genericError: 'Échec de la connexion ({status})',
|
||
},
|
||
sessions: {
|
||
title: 'Sessions',
|
||
refresh: 'Rafraîchir',
|
||
empty: 'Aucune session — démarrez-en une ci-dessous.',
|
||
newSession: 'Nouvelle session',
|
||
cwdLabel: 'Répertoire de travail',
|
||
cwdPlaceholder: '/chemin/absolu/du/projet',
|
||
commandLabel: 'Commande',
|
||
creating: 'Création…',
|
||
open: 'Ouvrir',
|
||
observe: 'Observer',
|
||
view: 'Voir',
|
||
resume: 'Reprendre',
|
||
fork: 'Dupliquer',
|
||
kill: 'Tuer',
|
||
confirmKill: 'Confirmer',
|
||
live: 'en cours',
|
||
resumable: 'reprenable',
|
||
sourceDiscovered: 'découverte',
|
||
hide: 'Masquer',
|
||
unhide: 'Réafficher',
|
||
hiddenBadge: 'masquée',
|
||
hideDiscovered: 'Masquer l’historique externe',
|
||
showHidden: 'Afficher les masquées',
|
||
hideHidden: 'Masquer les masquées',
|
||
archive: 'Archiver',
|
||
unarchive: 'Désarchiver',
|
||
archivedBadge: 'archivée',
|
||
showArchived: 'Afficher les archivées',
|
||
hideArchived: 'Masquer les archivées',
|
||
clients: 'aucun client | 1 client | {n} clients',
|
||
exitCode: 'code de sortie {code}',
|
||
statusLabel: {
|
||
starting: 'démarrage',
|
||
running: 'en cours',
|
||
exited: 'terminée',
|
||
},
|
||
registryStatus: {
|
||
busy: 'occupée',
|
||
idle: 'disponible',
|
||
waiting: 'en attente',
|
||
},
|
||
dialog: {
|
||
waiting: 'En attente de votre saisie',
|
||
deny: 'Refuser (Échap)',
|
||
kind: {
|
||
trust: 'Confiance',
|
||
permission: 'Permission',
|
||
question: 'Question',
|
||
plan: 'Plan',
|
||
},
|
||
},
|
||
},
|
||
dashboard: {
|
||
title: 'Worktrees',
|
||
allSessions: 'Toutes les sessions',
|
||
groups: 'Groupes',
|
||
},
|
||
groups: {
|
||
title: 'Groupes',
|
||
new: 'Nouveau groupe',
|
||
create: 'Créer',
|
||
creating: 'Création…',
|
||
nameLabel: 'Nom du groupe',
|
||
namePlaceholder: 'ex. Stack paiements',
|
||
colorLabel: 'Couleur',
|
||
reposLabel: 'Dépôts',
|
||
empty: 'Aucun groupe — créez-en un ci-dessus.',
|
||
noRepos: 'Aucun dépôt sélectionné.',
|
||
noReposInGroup: 'Aucun dépôt dans ce groupe — ajoutez-en ci-dessous.',
|
||
noReposRegistered: 'Aucun dépôt enregistré — ajoutez-en d’abord depuis le tableau de bord.',
|
||
open: 'Ouvrir',
|
||
edit: 'Modifier les dépôts',
|
||
editDone: 'Terminé',
|
||
remove: 'Supprimer',
|
||
confirmDelete: 'Confirmer',
|
||
repoCount: 'aucun dépôt | 1 dépôt | {n} dépôts',
|
||
dashboard: 'Tableau de bord',
|
||
missingRepo: 'Dépôt indisponible',
|
||
removeFromGroup: 'Retirer du groupe',
|
||
sessionsActive: 'aucune session active | 1 session active | {n} sessions actives',
|
||
viewList: 'Dépôts',
|
||
viewGrid: 'Terminaux',
|
||
gridEmpty: 'Aucune session active dans ce groupe.',
|
||
gridCapped: '{shown} sessions affichées sur {total} — fermez des terminaux pour voir le reste.',
|
||
newFeature: 'Nouvelle session de groupe',
|
||
spanBadge: 'groupe · {n} dépôt | groupe · {n} dépôts',
|
||
},
|
||
crossRepo: {
|
||
title: 'Nouvelle session de groupe',
|
||
intro: 'Lance UNE session Claude couvrant tous les dépôts du groupe — une seule conversation reliant l’ensemble.',
|
||
modeLabel: 'Répertoires',
|
||
modeFeature: 'Nouvelle branche dans chaque dépôt',
|
||
modeMain: 'Checkouts principaux',
|
||
branchLabel: 'Nom de branche',
|
||
branchPlaceholder: 'feature/…',
|
||
branchHint: 'Créée si absente, réutilisée si déjà présente dans le dépôt.',
|
||
baseRefLabel: 'Branche de base (optionnel)',
|
||
baseRefPlaceholder: 'branche par défaut du dépôt',
|
||
commandLabel: 'Session',
|
||
reposLabel: 'Dépôts de la session',
|
||
launch: 'Lancer la session',
|
||
launching: 'Lancement…',
|
||
close: 'Fermer',
|
||
ok: 'worktree prêt',
|
||
error: 'échec',
|
||
skippedLabel: 'ignoré',
|
||
done: 'Session de groupe démarrée.',
|
||
sessionFailed: 'Impossible de démarrer la session.',
|
||
},
|
||
repos: {
|
||
add: 'Ajouter un repo',
|
||
adding: 'Ajout…',
|
||
remove: 'Retirer',
|
||
pathLabel: 'Chemin du dépôt',
|
||
pathPlaceholder: '/chemin/absolu/du/repo',
|
||
empty: 'Aucun dépôt enregistré — ajoutez-en un ci-dessus, ou lancez un scan.',
|
||
invalid: 'indisponible',
|
||
scan: 'Scanner',
|
||
scanResult: 'Aucun nouveau dépôt trouvé | 1 nouveau dépôt ajouté | {n} nouveaux dépôts ajoutés',
|
||
hide: 'Masquer',
|
||
show: 'Afficher',
|
||
showHidden: 'Afficher les masqués ({n})',
|
||
},
|
||
worktrees: {
|
||
new: 'Nouveau worktree',
|
||
create: 'Créer',
|
||
creating: 'Création…',
|
||
branch: 'Branche',
|
||
newBranch: 'créer la branche',
|
||
baseRefLabel: 'Branche de base',
|
||
baseRefPlaceholder: 'branche par défaut',
|
||
start: 'Démarrer',
|
||
starting: 'Démarrage…',
|
||
startNone: 'aucune session',
|
||
startWork: 'Démarrer le travail',
|
||
modeLabel: 'Mode',
|
||
modeWorktree: 'Worktree',
|
||
modeMain: 'Branche principale',
|
||
branchModeLabel: 'Branche',
|
||
currentBranch: 'branche actuelle',
|
||
newBranchOpt: 'nouvelle branche',
|
||
commandLabel: 'Commande',
|
||
delete: 'Supprimer',
|
||
confirmDelete: 'Confirmer',
|
||
forceDelete: 'Forcer la suppression',
|
||
prune: 'Élaguer',
|
||
commit: 'Commit',
|
||
commitPlaceholder: 'Message de commit',
|
||
committing: 'Commit…',
|
||
push: 'Push',
|
||
pushing: 'Push…',
|
||
promote: 'Passer en principal',
|
||
promoting: 'Promotion…',
|
||
promoteConfirm:
|
||
'La branche « {branch} » deviendra le checkout principal du dépôt ; ce worktree sera supprimé (l’ancienne branche principale est conservée). Continuer ?',
|
||
forcePromote: 'Forcer (arbre modifié)',
|
||
main: 'principal',
|
||
detached: 'détaché',
|
||
locked: 'verrouillé',
|
||
prunable: 'élaguable',
|
||
clean: 'propre',
|
||
dirty: '{n} modifié(s)',
|
||
noSession: 'aucune session',
|
||
externalSessions: 'externes',
|
||
showExternalSessions: 'Afficher les sessions externes ({n})',
|
||
},
|
||
project: {
|
||
new: 'Nouveau projet',
|
||
title: 'Nouveau projet',
|
||
intro: 'Crée un nouveau dossier sous la racine choisie, puis y lance une session.',
|
||
nameLabel: 'Nom du projet',
|
||
namePlaceholder: 'mon-projet',
|
||
rootLabel: 'Dossier racine',
|
||
rootPlaceholder: '/chemin/absolu/racine',
|
||
gitInit: 'Initialiser un dépôt git (git init)',
|
||
commandLabel: 'Commande',
|
||
create: 'Créer',
|
||
creating: 'Création…',
|
||
},
|
||
workspace: {
|
||
open: 'Ouvrir l’IDE',
|
||
files: 'Fichiers',
|
||
changes: 'Changements',
|
||
noChanges: 'Aucun changement',
|
||
changesTruncated: 'Trop de changements — liste tronquée.',
|
||
terminal: 'Terminal',
|
||
editor: 'Éditeur',
|
||
diff: 'Diff',
|
||
noFileOpen: 'Aucun fichier ouvert',
|
||
noFileHint: 'Choisissez un fichier dans l’arbre pour l’éditer, ou un fichier modifié pour voir son diff.',
|
||
noSession: 'Aucune session ici',
|
||
noSessionHint: 'Lancez une session sur ce worktree depuis le tableau de bord pour obtenir un terminal.',
|
||
},
|
||
editor: {
|
||
save: 'Enregistrer',
|
||
unsaved: 'Modifications non enregistrées',
|
||
conflict: 'Ce fichier a changé sur le disque depuis son ouverture.',
|
||
reload: 'Recharger',
|
||
overwrite: 'Écraser',
|
||
},
|
||
diff: {
|
||
binary: 'Fichier binaire — pas de diff texte.',
|
||
tooLarge: 'Diff trop volumineux à afficher.',
|
||
noChanges: 'Aucun changement dans ce fichier.',
|
||
},
|
||
git: {
|
||
ahead: 'commits en avance',
|
||
behind: 'commits en retard',
|
||
staged: 'indexé',
|
||
unstaged: 'non indexé',
|
||
conflicts: 'conflits',
|
||
},
|
||
commit: {
|
||
staged: 'Indexés',
|
||
changes: 'Changements',
|
||
stage: 'Indexer',
|
||
unstage: 'Désindexer',
|
||
stageAll: 'Tout indexer',
|
||
unstageAll: 'Tout désindexer',
|
||
discard: 'Abandonner',
|
||
confirmDiscard: 'Confirmer l’abandon (destructif)',
|
||
amend: 'Amender le dernier commit',
|
||
amendPlaceholder: 'Nouveau message (vide = conserver le précédent)',
|
||
messagePlaceholder: 'Message de commit…',
|
||
commit: 'Commit',
|
||
push: 'Push',
|
||
fetch: 'Fetch',
|
||
pull: 'Pull (fast-forward)',
|
||
pullRebase: 'Pull --rebase',
|
||
alreadyPushed: 'Amend impossible : ce commit a déjà été poussé.',
|
||
},
|
||
gitconn: {
|
||
title: 'Connexions git',
|
||
hint: 'Connectez Gitea, GitLab ou GitHub pour cloner des dépôts privés. Les tokens sont chiffrés au repos et jamais ré-affichés.',
|
||
empty: 'Aucune connexion pour l’instant.',
|
||
addConnection: 'Ajouter une connexion',
|
||
add: 'Ajouter',
|
||
service: 'Service',
|
||
authType: 'Authentification',
|
||
pat: 'Jeton d’accès personnel',
|
||
appPassword: 'Mot de passe d’application',
|
||
label: 'Libellé',
|
||
labelPlaceholder: 'ex. Mon Gitea',
|
||
baseUrl: 'URL de l’instance',
|
||
username: 'Identifiant',
|
||
usernamePlaceholder: 'optionnel',
|
||
token: 'Jeton',
|
||
password: 'Mot de passe',
|
||
test: 'Tester',
|
||
added: 'Connexion ajoutée',
|
||
deleted: 'Connexion supprimée',
|
||
testOk: 'Connecté en tant que {user}',
|
||
testFailed: 'Échec de connexion : {error}',
|
||
},
|
||
clone: {
|
||
button: 'Cloner',
|
||
title: 'Cloner un dépôt',
|
||
noCredential: 'Aucune connexion git configurée.',
|
||
goSettings: 'En ajouter dans les Réglages',
|
||
credential: 'Connexion',
|
||
search: 'Rechercher',
|
||
searchPlaceholder: 'Filtrer les dépôts…',
|
||
private: 'privé',
|
||
noRepos: 'Aucun dépôt trouvé.',
|
||
more: 'Charger plus',
|
||
dest: 'Dossier de destination',
|
||
destPlaceholder: '/chemin/du/clone',
|
||
destHint: 'Doit être sous un dossier de scan configuré ; le dossier est créé par le clone.',
|
||
clone: 'Cloner',
|
||
starting: 'Démarrage…',
|
||
cloning: 'Clonage…',
|
||
done: 'Clone terminé',
|
||
failed: 'Échec du clone',
|
||
back: 'Retour',
|
||
},
|
||
terminal: {
|
||
observer: 'observateur (lecture seule)',
|
||
sessionEnded: 'Session terminée',
|
||
back: 'Sessions',
|
||
notAttachable:
|
||
'Cette session tourne hors d’Arboretum — dupliquez-la pour interagir, ou reprenez-la une fois arrêtée.',
|
||
fullscreen: 'Plein écran',
|
||
exitFullscreen: 'Quitter le plein écran',
|
||
maximize: 'Agrandir',
|
||
restore: 'Réduire',
|
||
openFullscreen: 'Ouvrir en plein écran',
|
||
group: 'Groupe',
|
||
covers: 'couvre',
|
||
},
|
||
push: {
|
||
enable: 'Activer les notifications',
|
||
disable: 'Notifications activées',
|
||
denied: 'Permission de notification refusée — activez-la dans les réglages du navigateur.',
|
||
unsupported: 'Le push nécessite HTTPS (ex. Tailscale Serve) ; sur iOS, installez d’abord l’app sur l’écran d’accueil.',
|
||
},
|
||
fs: {
|
||
browse: 'Parcourir…',
|
||
up: 'Remonter',
|
||
useFolder: 'Utiliser ce dossier',
|
||
showHidden: 'Afficher les cachés',
|
||
loading: 'Chargement…',
|
||
empty: 'Aucun sous-dossier',
|
||
repoBadge: 'dépôt',
|
||
},
|
||
ws: {
|
||
reconnecting: 'Connexion perdue — reconnexion…',
|
||
},
|
||
nav: {
|
||
worktrees: 'Worktrees',
|
||
sessions: 'Sessions',
|
||
groups: 'Groupes',
|
||
settings: 'Réglages',
|
||
help: 'Aide',
|
||
more: 'Plus',
|
||
gitea: 'Code source',
|
||
buymeacoffee: 'Offrez-moi un café',
|
||
waiting: 'en attente',
|
||
},
|
||
controls: {
|
||
searchPlaceholder: 'Rechercher…',
|
||
results: 'aucun résultat | 1 résultat | {n} résultats',
|
||
sortBy: 'Trier par',
|
||
filters: 'Filtres',
|
||
clearAll: 'Effacer',
|
||
},
|
||
sort: {
|
||
asc: 'Croissant',
|
||
desc: 'Décroissant',
|
||
session: {
|
||
state: 'État',
|
||
recent: 'Plus récentes',
|
||
clients: 'Clients',
|
||
cwd: 'Répertoire',
|
||
command: 'Commande',
|
||
},
|
||
worktree: {
|
||
main: 'Principal d’abord',
|
||
branch: 'Branche',
|
||
dirty: 'Modifications',
|
||
ahead: 'En avance',
|
||
behind: 'En retard',
|
||
activity: 'Activité',
|
||
},
|
||
repo: {
|
||
label: 'Nom',
|
||
created: 'Créé le',
|
||
worktrees: 'Worktrees',
|
||
activity: 'Activité',
|
||
},
|
||
group: {
|
||
label: 'Nom',
|
||
created: 'Créé le',
|
||
repos: 'Dépôts',
|
||
activeSessions: 'Sessions actives',
|
||
},
|
||
},
|
||
filter: {
|
||
state: {
|
||
label: 'État',
|
||
live: 'Active',
|
||
waiting: 'En attente',
|
||
busy: 'Occupée',
|
||
idle: 'Disponible',
|
||
exited: 'Terminée',
|
||
resumable: 'Reprenable',
|
||
},
|
||
command: {
|
||
label: 'Commande',
|
||
},
|
||
source: {
|
||
label: 'Source',
|
||
managed: 'Gérée',
|
||
discovered: 'Découverte',
|
||
},
|
||
repo: {
|
||
label: 'Dépôt',
|
||
},
|
||
worktree: {
|
||
dirtiness: 'Modifications',
|
||
dirty: 'Modifié',
|
||
clean: 'Propre',
|
||
session: 'Session',
|
||
with: 'Avec session',
|
||
without: 'Sans session',
|
||
flags: 'Drapeaux',
|
||
locked: 'Verrouillé',
|
||
prunable: 'Élaguable',
|
||
},
|
||
},
|
||
pagination: {
|
||
prev: 'Précédent',
|
||
next: 'Suivant',
|
||
pageOf: 'Page {page} / {pageCount}',
|
||
perPage: 'Par page',
|
||
all: 'Tout',
|
||
},
|
||
palette: {
|
||
placeholder: 'Aller à un dépôt, worktree, session, groupe…',
|
||
empty: 'Aucun résultat',
|
||
hint: '↑↓ naviguer · ↵ ouvrir · échap fermer',
|
||
types: {
|
||
repo: 'Dépôt',
|
||
worktree: 'Worktree',
|
||
session: 'Session',
|
||
group: 'Groupe',
|
||
action: 'Action',
|
||
},
|
||
actions: {
|
||
newSession: 'Nouvelle session',
|
||
addRepo: 'Ajouter un dépôt',
|
||
newGroup: 'Nouveau groupe',
|
||
},
|
||
},
|
||
toast: {
|
||
sessionCreated: 'Session démarrée',
|
||
sessionKilled: 'Session tuée',
|
||
sessionResumed: 'Session reprise',
|
||
sessionForked: 'Session dupliquée',
|
||
sessionHidden: 'Session masquée',
|
||
sessionUnhidden: 'Session réaffichée',
|
||
sessionsHidden: 'aucune session masquée | 1 session masquée | {n} sessions masquées',
|
||
sessionArchived: 'Session archivée',
|
||
sessionUnarchived: 'Session désarchivée',
|
||
repoAdded: 'Dépôt ajouté',
|
||
repoRemoved: 'Dépôt retiré',
|
||
worktreeCreated: 'Worktree créé',
|
||
worktreeDeleted: 'Worktree supprimé',
|
||
pruned: 'Worktrees élagués',
|
||
groupCreated: 'Groupe créé',
|
||
groupUpdated: 'Groupe mis à jour',
|
||
groupDeleted: 'Groupe supprimé',
|
||
groupSessionLaunched: 'Session de groupe démarrée',
|
||
groupSessionPartial: 'Session de groupe démarrée ({n} dépôt(s) ignoré(s))',
|
||
projectCreated: 'Projet créé',
|
||
genericError: 'Une erreur est survenue',
|
||
dismiss: 'Fermer',
|
||
},
|
||
attention: {
|
||
title: 'À traiter',
|
||
count: 'aucune session en attente | 1 session en attente | {n} sessions en attente',
|
||
empty: 'Rien à traiter',
|
||
},
|
||
settings: {
|
||
title: 'Réglages',
|
||
// Préférences
|
||
preferences: 'Préférences',
|
||
preferencesHint: 'Ces réglages ne s’appliquent qu’à ce navigateur.',
|
||
language: 'Langue',
|
||
notifications: 'Notifications',
|
||
notificationsEnabled: 'Activées — vous serez notifié lorsqu’une session attend une réponse.',
|
||
notificationsDisabled: 'Désactivées.',
|
||
enableNotifications: 'Activer les notifications',
|
||
disableNotifications: 'Désactiver les notifications',
|
||
testNotification: 'Envoyer un test',
|
||
testSent: 'Notification de test envoyée',
|
||
pushUnsupported: 'Le push exige HTTPS (ex. Tailscale Serve) ; sur iOS, installez d’abord l’app sur l’écran d’accueil.',
|
||
// Accès & sécurité
|
||
security: 'Accès & sécurité',
|
||
securityHint: 'Les jetons donnent un accès complet à ce serveur. Créez-en un par appareil et révoquez ceux que vous n’utilisez plus.',
|
||
tokens: 'Jetons d’accès',
|
||
newTokenLabel: 'Libellé',
|
||
newTokenPlaceholder: 'ex. téléphone, portable',
|
||
createToken: 'Créer un jeton',
|
||
tokenCreated: 'Jeton créé',
|
||
copyTokenHint: 'Copiez ce jeton maintenant — par sécurité il ne sera plus jamais affiché.',
|
||
copy: 'Copier',
|
||
copied: 'Copié',
|
||
current: 'courant',
|
||
created: 'Créé le {date}',
|
||
lastUsed: 'utilisé le {date}',
|
||
neverUsed: 'jamais utilisé',
|
||
revoke: 'Révoquer',
|
||
confirmRevoke: 'Confirmer la révocation',
|
||
tokenRevoked: 'Jeton révoqué',
|
||
lastTokenError: 'Impossible de révoquer le dernier jeton actif — créez-en un autre d’abord.',
|
||
save: 'Enregistrer',
|
||
saved: 'Enregistré',
|
||
// Sécurité & conformité
|
||
compliance: 'Sécurité & conformité',
|
||
complianceHint: 'Exportez ou effacez les données liées à votre jeton (RGPD), et consultez le journal d’audit des opérations sensibles.',
|
||
exportData: 'Exporter mes données',
|
||
refreshAudit: 'Journal d’audit',
|
||
deleteData: 'Effacer mes données',
|
||
deleteConfirm: 'Effacer les données liées à votre jeton (abonnements push) et révoquer ce jeton ? Action irréversible.',
|
||
deleteDone: 'Vos données ont été effacées.',
|
||
// Découverte des dépôts
|
||
discovery: 'Découverte des dépôts',
|
||
discoveryHint: 'Arboretum scanne ces dossiers à la recherche de dépôts git et les enregistre automatiquement. Les dépôts masqués sont conservés et jamais ré-ajoutés.',
|
||
scanRoots: 'Dossiers à scanner',
|
||
scanRootsEmpty: 'Aucun dossier configuré — votre dossier personnel est utilisé par défaut.',
|
||
addRoot: 'Ajouter un dossier',
|
||
removeRoot: 'Retirer',
|
||
scanInterval: 'Intervalle de re-scan (minutes)',
|
||
scanIntervalHint: '0 désactive le scan périodique. Les changements prennent effet au prochain redémarrage du daemon.',
|
||
// Sessions (rétention / archivage auto)
|
||
sessions: 'Sessions',
|
||
sessionsHint: 'Les sessions terminées plus anciennes que la fenêtre de rétention sont archivées automatiquement (masquées de la liste par défaut). Rien n’est supprimé — une session archivée reste reprenable et forkable.',
|
||
retentionDays: 'Auto-archiver après (jours)',
|
||
retentionDaysHint: '0 n’archive jamais. Les sessions archivées sont masquées par défaut ; activez « Afficher les archivées » dans la liste pour les voir.',
|
||
// Claude CLI
|
||
claudeCli: 'CLI Claude',
|
||
claudeCliHint: 'Où Arboretum trouve le binaire `claude` et ses données. Utile quand le daemon tourne en service avec un PATH minimal qui n’inclut pas ~/.local/bin.',
|
||
claudeBinStatusOk: 'Détecté',
|
||
claudeBinStatusNotFound: 'Introuvable — impossible de lancer une session tant que ce n’est pas résolu.',
|
||
claudeBinStatusBadPath: 'Le chemin configuré n’est pas un fichier exécutable.',
|
||
claudeBinSourceConfigured: 'configuré',
|
||
claudeBinSourcePath: 'PATH',
|
||
claudeBinPathLabel: 'Chemin du binaire (override)',
|
||
claudeBinPathHint: 'Chemin absolu vers l’exécutable `claude`. Laisser vide pour l’auto-détection via le PATH. Prend effet à la prochaine session.',
|
||
claudeBinPathPlaceholder: 'ex. /home/vous/.local/bin/claude',
|
||
claudeHomeLabel: 'Répertoire ~/.claude',
|
||
claudeHomeHint: 'Surcharge l’emplacement de ~/.claude (transcripts & registre des sessions). Prend effet au redémarrage du daemon.',
|
||
claudeHomePlaceholder: 'ex. /home/vous/.claude',
|
||
// Serveur (lecture seule)
|
||
server: 'Serveur',
|
||
serverHint: 'Définis au démarrage via des flags CLI — les modifier nécessite de redémarrer le daemon.',
|
||
version: 'Version',
|
||
port: 'Port',
|
||
bind: 'Adresse de liaison',
|
||
allowedOrigins: 'Origines autorisées',
|
||
dataDir: 'Répertoire de données',
|
||
vapidPublicKey: 'Clé publique VAPID',
|
||
vapidContact: 'Contact VAPID',
|
||
none: 'aucune',
|
||
flagHint: 'Flag CLI : {flag}',
|
||
// Soutien
|
||
support: 'Soutenir le projet',
|
||
supportHint: 'Arboretum est un projet personnel libre et auto-financé. S’il vous fait gagner du temps, vous pouvez soutenir son développement.',
|
||
supportCta: 'Offrez-moi un café',
|
||
},
|
||
help: {
|
||
title: 'Aide',
|
||
intro: 'Tout ce qu’Arboretum sait faire, et comment l’utiliser.',
|
||
searchPlaceholder: 'Rechercher dans l’aide…',
|
||
noMatch: 'Aucun sujet correspondant',
|
||
},
|
||
};
|
||
|
||
export default fr;
|