feat: add host-local custom project icons (#2335)

* feat(projects): add local icons and colors

* refactor(projects): simplify appearance handling

* fix(projects): serialize appearance saves

* test(app): update project appearance expectations

* test: fix project appearance CI expectations

* refactor(projects): organize appearance code

* fix(server): adopt main's reconcile model in project appearance updates

* fix(projects): preserve host-local appearance targets

* fix(desktop): restore Linux development startup

Ubuntu can block Electron's unprivileged user-namespace fallback while the npm-installed sandbox helper is not SUID. Disable the Chromium process sandbox only in the Linux development runner so packaged desktop policy remains unchanged.

* feat(projects): add custom project icons

Keep URL acquisition in the client so the host daemon only validates uploaded bytes. Project name and icon changes share one adaptive edit sheet.

* refactor(settings): scope projects by host

---------

Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
This commit is contained in:
nikuscs
2026-08-01 01:34:42 +08:00
committed by GitHub
co-authored by Mohamed Boudra
parent 706ae3d9bb
commit 800bd2bef1
67 changed files with 2158 additions and 912 deletions
+12 -13
View File
@@ -1668,6 +1668,7 @@ export const fr: TranslationResources = {
vimHint: "S’applique aux fichiers source sur le web et le bureau.",
},
hostSections: {
projects: "Projets",
connections: "Relations",
agents: "Agents",
workspaces: "Workspaces",
@@ -2177,25 +2178,23 @@ export const fr: TranslationResources = {
},
},
project: {
noEditableTarget:
"Nous n'avons pas de copie modifiable de ce projet sur aucun hôte connecté.",
noEditableTarget: "Ce projet n'est pas modifiable sur cet hôte.",
backToProjects: "Retour aux projets",
switchHost: "Changer d'hôte",
rename: {
renamedToast: "Projet renommé",
errorFallback: "Impossible de renommer le projet",
renameLabel: "Renommer le projet",
resetLabel: "Réinitialiser le nom du projet par défaut",
projectNameLabel: "Nom du projet",
saveLabel: "Enregistrer le nom du projet",
cancelLabel: "Annuler le changement de nom",
reset: "Réinitialiser",
edit: {
title: "Modifier le projet",
name: "Nom",
nameLabel: "Nom du projet",
icon: "Icône",
chooseImage: "Choisir une image",
useAutomatic: "Utiliser l'automatique",
imageUrl: "URL d'image ou de site",
save: "Enregistrer",
savedToast: "Projet mis à jour",
},
readFailures: {
invalidTitle: "paseo.json n'a pas pu être analysé",
invalidDescription: "Corrigez le fichier sur le disque, puis rechargez.",
missingTitle: "Cet hôte n'a pas ce projet",
missingWithHosts: "Basculez vers un autre hôte ci-dessus ou rechargez.",
missingSingleHost: "L'hôte sélectionné n'a aucune trace de ce projet.",
transportTitle: "Impossible de charger paseo.json",
transportFallback: "L'hôte n'a pas répondu.",