Commit Graph
69 Commits
Author SHA1 Message Date
johanleroy 0c191b1296 release: git-arboretum 3.7.1 (transcripts préservés), desktop 0.2.5 (mise à jour automatique)
CI / No em/en dashes (push) Successful in 3s
CI / Build & test (Node 24) (push) Successful in 11m5s
Release / Publish to Gitea npm registry (push) Successful in 11m10s
CI / Build & test (Node 22) (push) Successful in 11m24s
Desktop Release / Build Linux (AppImage + deb) (push) Successful in 13m57s
Desktop Release / Publish floating desktop-latest release (push) Successful in 10s
CI / Pack & boot smoke (Node 22) (push) Successful in 9m54s
2026-08-05 11:35:59 +02:00
johanleroy 17e95754b1 fix(server, desktop): plus de transcript perdu, et la mise à jour s'applique toute seule
Deux défauts vécus sur le poste, tous deux « invisibles » jusqu'à ce qu'on regarde.

1. Une console Claude ouverte depuis l'app affichait « Transcript saving is off,
   inherited CLAUDE_CODE_CHILD_SESSION marker ». Le daemon avait été lancé depuis
   une session Claude Code, il héritait donc de ses marqueurs d'exécution et les
   repassait à CHAQUE session qu'il lance. Le CLI se croyait sous-session et
   coupait la sauvegarde de son transcript : plus d'historique, plus de --resume,
   claudeSessionId restant null (et avec lui l'état fin busy/waiting/idle, ce qui
   explique les sessions sans activité détectée). L'environnement des PTY est
   desormais assaini de ces marqueurs, pour `claude` comme pour les shells (un
   `claude` tapé à la main en héritait aussi). La configuration légitime de
   l'utilisateur (CLAUDE_CONFIG_DIR, ANTHROPIC_*, proxies) passe intacte.
   Vérifié par acceptance-p17 : le daemon de test est lancé avec un environnement
   volontairement pollué, et le PTY n'en voit plus rien.

2. Une mise à jour installée à chaud demandait encore une manipulation. La 0.2.4
   détectait le remplacement du binaire et proposait un dialogue « Restart now » :
   le travail restait à la charge de l'utilisateur. L'app redémarre maintenant
   d'elle-même quand cela ne coûte rien, c'est-à-dire le cas courant, et ne
   demande que s'il y a quelque chose à perdre : des sessions vivantes à
   interrompre (le dialogue dit combien) ou un daemon injoignable. Un « Later »
   reste définitif pour cette version : rien ne redémarre dans le dos de
   personne. La détection ne dépend plus d'un retour par le tray ou le Dock : un
   `stat` toutes les 30 s la couvre même fenêtre ouverte, par poll et non par
   `fs.watch`, qui ne voit souvent rien quand un paquet remplace un binaire ou
   tout un répertoire.
2026-08-05 11:35:51 +02:00
johanleroy dc8c7c9534 release: git-arboretum 3.7.0 (fin de l'écran noir, colonnes de terminaux, git scopé), desktop 0.2.4
CI / No em/en dashes (push) Successful in 4s
CI / Build & test (Node 24) (push) Successful in 10m50s
CI / Build & test (Node 22) (push) Successful in 11m5s
Release / Publish to Gitea npm registry (push) Successful in 10m57s
Desktop Release / Build Linux (AppImage + deb) (push) Successful in 13m27s
Desktop Release / Publish floating desktop-latest release (push) Successful in 10s
CI / Pack & boot smoke (Node 22) (push) Successful in 9m55s
Le desktop 0.2.4 embarque le daemon 3.7.0 et livre aussi les garde-fous de
démarrage déjà sur main (dialogue d'échec, reprise d'un daemon orphelin,
redémarrage après mise à jour installée à chaud).
2026-08-05 10:57:05 +02:00
johanleroy 8aea0ae32d fix(server, web, vscode): les terminaux ne restent plus noirs, panes côte à côte, git scopé au terminal
Un terminal pouvait rester tout noir alors que sa session tournait. Le PTY était
vivant et avait bien écrit sa sortie : la panne était dans le transport. Le replay
d'attache est une frame BINAIRE, mais un client n'apprend son numéro de canal
qu'avec le message `attached` ; le serveur envoyait le replay AVANT, donc tout
client le jetait sur un canal inconnu. Rien n'était peint, et un TUI au repos
(Claude à son prompt) ne réémet jamais rien de lui-même. `attach()` renvoie
désormais le replay et la gateway l'émet APRÈS `attached` : un seul correctif
serveur répare le web, l'app de bureau et l'extension VS Code, qui portaient le
même défaut client. Le resize de l'attache masquait le bug en provoquant un
SIGWINCH, d'où son apparence intermittente.

Seconde moitié du symptôme (« je tape et rien ne se passe ») : le dock montait
avant la liste des sessions, en déduisait « non attachable » et s'attachait en
observateur, à vie et en silence. Un pane n'attache plus avant de connaître sa
session (`sessions.loaded`).

Attaches sans écran : le message `attach` accepte un `screen` optionnel (défaut
true). Un client qui n'affiche rien et veut seulement répondre à un dialogue ne
prend plus le contrôle de la session, ne lui impose plus ses dimensions (ce qui
figeait la géométrie du vrai terminal) et ne reçoit plus le flux pour le jeter.

Rendre les pannes visibles : la raison d'un exit est écrite dans le terminal
(`[arboretum] bash exited with code 3`) avant le détachement ; un repaint est
forcé si rien n'arrive 1,2 s après l'attache, puis annoncé avec « Refresh
screen » ; les refus de canal remontent à l'écran au lieu d'un console.warn ; le
chemin du CLI claude est revalidé (périmé après une bascule nvm/asdf, le PTY
mourait sans un octet).

Colonnes de terminaux : le dock devient une rangée de colonnes redimensionnables
(3 max), chacune avec ses onglets. Algèbre pure dans lib/dock-model.ts, cinq
invariants documentés, ratios plutôt que pixels. `dockSessionIds` et
`activeDockSessionId` deviennent des computed dérivés : aucun consommateur ni
test existant ne change. Alt+clic ouvre à côté depuis les quatre panneaux. Le
plafond de hauteur du dock suit le viewport au lieu d'un 640 px figé. Correctif
préexistant au passage : PanelSplitter passait ses bornes par valeur, figées au
premier rendu, alors que le clavier les relisait.

Portée git : la vue Changements suit le worktree du terminal focalisé, ou tous
les dépôts de son groupe pour une session de groupe, avec « tout voir » à un
clic. L'index Git de la sidebar reste global (c'est la sortie d'une portée
étroite) et le badge d'activité aussi (il sert à signaler le travail qu'on ne
regarde pas). Seul le TERMINAL impose le contexte : le repli sur l'onglet
éditeur, essayé d'abord, rétrécissait la vue multi-projet dès qu'on ouvrait un
fichier.

Vérifications : acceptance-p17.mjs prouve l'ordre des trames sur un vrai
WebSocket (avec l'ancien ordre : 0 octet rejoué, échec), verify-terminals.mjs
prouve par interaction réelle que le terminal peint, que deux colonnes
coexistent, que la frappe atteint le bon PTY (fichier témoin par cwd) et que la
vue suit le terminal.
2026-08-05 10:56:42 +02:00
johanleroy c6deded0c6 release: git-arboretum 3.6.0 (ouverture des fichiers réparée, vue Changements par projet), desktop 0.2.3
CI / No em/en dashes (push) Successful in 3s
CI / Build & test (Node 24) (push) Successful in 11m1s
Release / Publish to Gitea npm registry (push) Successful in 11m6s
CI / Build & test (Node 22) (push) Successful in 11m17s
Desktop Release / Build Linux (AppImage + deb) (push) Successful in 14m18s
Desktop Release / Publish floating desktop-latest release (push) Successful in 12s
CI / Pack & boot smoke (Node 22) (push) Successful in 9m57s
Desktop Release / Build Windows (NSIS + portable) (push) Canceled after 0s
Le daemon 3.6.0 corrige la zone d'édition qui pouvait rester vide et ajoute la
bascule Fichiers / Changements au centre de l'IDE. Le shell Electron est inchangé,
seule la version du daemon embarqué change.
2026-08-04 23:19:16 +02:00
johanleroy ce224fd470 fix(web): les fichiers s'ouvrent enfin, et le travail git par projet au centre
Deux défauts d'usage de la zone centrale de l'IDE.

1. Ouvrir un fichier affichait une page vide. Le conteneur de l'unique instance
   Monaco vivait sous le `v-if="activeTab"` : monté sans onglet actif (premier
   usage, ou après avoir tout fermé), `onMounted` sortait en silence sur
   `!host.value`, `ready` restait faux pour toujours, et les deux watchers
   d'affichage étaient gardés par lui. Le conteneur est désormais toujours monté
   (v-show, jamais v-if : sous un v-if, fermer le dernier onglet détruisait le
   DOM et l'éditeur gardait une référence sur un noeud détaché) et l'éditeur est
   créé paresseusement depuis `showTab`, devenu l'unique entonnoir d'affichage.
   `useMonaco` ne mémoïse plus un échec, l'attente et l'erreur sont visibles, et
   la relecture disque ne se tait plus. Sur mobile, ouvrir un fichier amène enfin
   la zone centrale au premier plan et la valeur morte `mobilePanel = 'sidebar'`
   disparaît (migrée).

   Trouvé par l'E2E : seul l'`editor.worker` était fourni, donc ouvrir un `.ts`
   lançait le service TypeScript contre un worker qui n'en connaissait pas les
   méthodes, et jetait un rejet non géré à chaque ouverture. Les workers de
   langage sont fournis (chunks à la demande), diagnostics sémantiques coupés
   (sans tsconfig ni node_modules, ils inventeraient des erreurs).

2. Le statut git était à l'étroit et mono-projet. La zone centrale porte un mode
   « Fichiers / Changements » (bascule à icônes dans la barre d'onglets, donc
   accessible même sans onglet ouvert). La vue Changements montre un bloc par
   worktree pour TOUS les projets ouverts : fichiers indexés et non indexés, diff
   déplié sur place, commit, push, fetch, pull et historique par bloc. Le panneau
   Git de la barre latérale devient l'index (compteurs déjà diffusés par WS, donc
   zéro requête) et le badge de la barre d'activité, codé à 0, compte enfin les
   worktrees à traiter.

   Au passage : `canPush` était faux dans les deux sens (actif sans rien à
   pousser, bloqué en étant seulement en retard), l'amend d'un message seul est
   accepté comme le serveur le permettait déjà, le rebase est proposé dès qu'on
   est en retard, une confirmation d'abandon ne survit plus au rechargement de la
   liste, et `commit`/`fetch`/`push` émettent enfin `worktree_changes` (le
   compteur « n non poussés » restait périmé juste après un push).

Vérifié : 528 tests, acceptations P7/P9/P14/P15, `verify-ui` (4 captures
nouvelles) et un `verify-editor` qui prouve par clics réels l'ouverture d'un
fichier sans onglet persisté, la fermeture/réouverture, la bascule mobile et le
chunk éditeur absent. Ce dernier échoue bien si l'on remet le conteneur sous un
v-if.
2026-08-04 23:18:40 +02:00
johanleroy 114fbc8ba0 fix(desktop, web): pont presse-papier Electron, sans quoi copier ne faisait rien dans l'app
CI / No em/en dashes (push) Successful in 3s
CI / Build & test (Node 24) (push) Successful in 10m48s
Release / Publish to Gitea npm registry (push) Successful in 10m52s
CI / Build & test (Node 22) (push) Successful in 11m6s
Desktop Release / Build Linux (AppImage + deb) (push) Successful in 13m38s
Desktop Release / Publish floating desktop-latest release (push) Successful in 11s
CI / Pack & boot smoke (Node 22) (push) Successful in 9m56s
Desktop Release / Build Windows (NSIS + portable) (push) Canceled after 0s
git-arboretum 3.5.1, desktop 0.2.2.

Le copier/coller livre en 3.5.0 ne fonctionnait que dans un navigateur : verifie dans l'app packagee,
`navigator.clipboard` y rejette en NotAllowedError A LA LECTURE COMME A L'ECRITURE. La copie echouait
donc silencieusement dans le contexte meme ou le probleme avait ete signale.

- feat(desktop): `arboretumDesktop.clipboard` expose par le preload, relaye en IPC vers le module
  `clipboard` d'Electron (lecture + ecriture, ecriture bornee a 1 M de caracteres). Le module
  `clipboard` n'etant pas accessible a un preload sandboxe, le passage par le main est obligatoire.
  Constantes de canaux isolees dans src/shared/ipc.ts pour que le bundle du preload ne tire pas
  `ipcMain` avec lui.
- fix(web): acces au presse-papier en cascade, du plus fiable au plus degrade : pont de l'app de
  bureau, puis `navigator.clipboard`, puis `document.execCommand('copy')` pour l'ecriture. Ce dernier
  recours couvre aussi l'acces LAN en clair (http://<ip>:7317), ou l'API Clipboard est indisponible.
- test: quatre cas de plus sur l'ordre de la cascade et le retour a null quand tout est refuse
  (501 tests). Pont IPC verifie dans un vrai Electron : writeText/readText repondent OK, alors que
  `navigator.clipboard` y refuse. Le chemin complet frappe -> copie -> collage -> SIGINT reste
  couvert par verify-clipboard.mjs (Chromium CDP, ALL GREEN).
2026-08-04 21:11:46 +02:00
johanleroy bde5358ea8 release: git-arboretum 3.5.0 (cache SPA, copier/coller terminal, fichiers des groupes), desktop 0.2.1
CI / No em/en dashes (push) Successful in 3s
CI / Build & test (Node 24) (push) Successful in 10m50s
CI / Build & test (Node 22) (push) Successful in 11m2s
Release / Publish to Gitea npm registry (push) Successful in 10m56s
Desktop Release / Build Linux (AppImage + deb) (push) Successful in 13m21s
Desktop Release / Publish floating desktop-latest release (push) Successful in 11s
CI / Pack & boot smoke (Node 22) (push) Successful in 9m53s
Desktop Release / Build Windows (NSIS + portable) (push) Canceled after 0s
Cause racine de l'ecran noir apres mise a jour : l'etag faible de @fastify/static derive de
taille+mtime, et npm pack fige le mtime de tout le tarball a une date constante (1985-10-26). Deux
index.html de versions differentes mais de meme taille partageaient donc le meme etag : le client
recevait un 304, gardait son index perime, et demandait des /assets/<hash> disparus ; le fallback SPA
repondait index.html en text/html pour ces modules, le navigateur refusait le script, rien ne peignait.

- fix(server): index.html et tous les fichiers non haches servis en no-store, validation
  conditionnelle desactivee (etag/lastModified) pour qu'un client bloque sur un index perime se
  repare seul ; /assets/ (noms haches) passent en immutable un an
- feat(web): copier/coller dans le terminal xterm, dont la selection n'est pas une selection DOM :
  Ctrl+Maj+C / Ctrl+Maj+V, Cmd+C / Cmd+V sur macOS, Ctrl+Inser / Maj+Inser, plus interception de
  l'evenement DOM copy pour que le Copier natif fonctionne. Ctrl+C reste SIGINT
- fix(web): script anti-FOUC sorti dans /theme-boot.js, la CSP script-src 'self' du daemon refusait
  de l'executer inline (le theme n'etait donc pose qu'au montage de la SPA)
- feat(web): les worktrees d'un groupe se deplient sur leur arborescence de fichiers dans le panneau
  Groupes (meme composant et meme etat d'expansion que l'Explorateur), et un worktree ainsi deplie
  est desormais surveille en temps reel
- fix: octet nul litteral remplace par \0 dans trois sources (stores/ide.ts, GitPanel.vue,
  vscode/repos-tree.ts) : git et grep les traitaient comme binaires, leurs diffs etaient
  illisibles en revue et la garde CI lint-dashes (git grep -I) les sautait en silence
- test: cacheControlFor et clipboardIntent en tests purs, verify-clipboard.mjs (E2E Chromium CDP :
  copie, collage et SIGINT prouves par le presse-papier reel et par le systeme de fichiers),
  capture groups-dark-desktop ajoutee a verify-ui.mjs
2026-08-04 16:23:33 +02:00
johanleroy 63f2697745 release: git-arboretum 3.4.0 (visibilité temps réel, historisation), desktop 0.2.0 (Windows, logo), vscode 0.4.1, site 0.4.0
CI / Build & test (Node 22) (push) Successful in 11m12s
CI / Build & test (Node 24) (push) Successful in 10m14s
CI / No em/en dashes (push) Successful in 3s
Deploy site (production) / build-and-deploy (push) Successful in 19s
CI / Pack & boot smoke (Node 22) (push) Has been cancelled
Tout est additif : PROTOCOL_VERSION inchangé, aucune rupture d'API.

Temps réel réellement armé
- `pinSession` n'était appelé nulle part : une session vivante épingle désormais le watcher FS de son
  worktree (`WorktreeManager.syncSessionPin` + `resolveWorktreeForCwd`), donc un worktree où un agent
  écrit se rafraîchit même si personne ne le regarde (mesuré ~350 ms).
- Les abonnements `watch` sortent de `GitPanel`, démonté dès qu'on quitte son onglet, ce qui coupait le
  seul abonnement de toute l'app : `composables/useWatchedWorktrees.ts` (monté dans App.vue) suit le
  worktree actif et les dépôts dépliés, borné à 40.
- Une coupure WS ne laisse plus l'UI sur des listes périmées : rechargement complet au retour.
- `worktree_changes` alimente `worktrees.changeVersion`, consommé par l'arbre de fichiers, le diff
  (son `:version` était câblé à 0) et l'éditeur, qui recharge un tampon propre ou lève la bannière de
  conflit avant la sauvegarde au lieu d'attendre le 409.

Corrélation session ↔ worktree par contenance (`@arboretum/shared/path-match.ts`)
- Un terminal lancé dans un sous-répertoire (« Démarrer le projet ») ou une session de groupe reliée
  par `--add-dir` apparaissent enfin sous leur worktree ; le worktree le plus spécifique gagne.
- Règle unique partagée par le daemon, le web et l'extension.

Historisation
- `commitLog` / `commitDiff` purs, `GET /repos/:id/worktrees/log` et `diff?commit=` (hash strictement
  validé, mêmes bornes que les diffs de fichiers).
- `CommitHistory.vue` sous le panneau Git : commits, marquage des non poussés, diff déplié sur place.

Visibilité
- Compteurs git complets sur chaque worktree de l'arbre et du panneau Groupes (ils n'existaient qu'en
  barre de statut, pour le seul worktree actif), avec upstream et dernier commit en infobulle ;
  `locked`, `prunable` et un dépôt invalide sont désormais visibles.
- Le panneau Groupes montre sa composition réelle (dépôts, worktrees, sessions) et teinte l'explorateur.

Polish visuel
- Les toasts d'erreur, persistants, s'empilaient derrière les modals : téléportés au-dessus.
- Sur mobile, ouvrir un terminal ou changer d'activité n'avait aucun effet visible.
- Tailles de panneaux clampées sur la fenêtre, barres d'onglets sans scrollbar parasite, états de
  chargement et d'erreur dans les trois panneaux, accessibilité des 11 modals centralisée dans
  ModalHost, splitters au clavier, numéros de diff collants, `window.confirm` remplacé.

Windows (daemon et packaging)
- `where.exe`, PowerShell comme shell de lancement, askpass `.cmd` (clone/push HTTPS par PAT),
  `taskkill /T`, `%APPDATA%`, `arboretum install` via tâche planifiée.
- Scripts de build exécutables sur un hôte Windows (`npm.cmd`, extraction sans `unzip` ni `bash`).
- Job CI `windows-latest` conditionné par ENABLE_WINDOWS_BUILD ; procédure runner dans docs/CI_RUNNERS.md.

Logo Debian : cause racine
- Une icône unique de 895×895 atterrissait dans `hicolor/895x895`, répertoire absent d'`index.theme`
  donc ignoré par la spécification freedesktop ; et `executableName` dérivait du nom scopé du paquet
  (`@arboretumdesktop`). Jeu d'icônes standard généré + `executableName: arboretum`, plus
  `deb.synopsis` (description courte vide dans apt) et `Section: devel`.
- Runtime Node embarqué élagué : 205 → 118 Mo.
- Auto-update réparé : la release flottante `desktop-latest` que les binaires interrogent n'existait pas.

Doc et vitrine
- README/README.fr : installation par plateforme, mode serveur web (nginx, LAN), dépannage, variables
  d'environnement, flags manquants.
- Doc in-app réécrite (elle renvoyait aux pages Worktrees et Sessions supprimées).
- Section « Accès distant » dans les Réglages ; le 403 BAD_ORIGIN nomme le flag à ajouter.
- Site : prérequis et registre npm privé (le `npx` affiché renvoyait un 404), téléchargements réels par
  plateforme, section « trois façons de l'utiliser », navigation complétée, 16 clés i18n mortes purgées.

Vérifications : 483 tests unitaires, 14 acceptances E2E vertes (dont p14/p15 nouvelles), captures de
rendu sans erreur console (nouveau `verify-ui.mjs`), .deb reconstruit et contrôlé (icônes aux tailles
standard, entrée .desktop valide).
2026-08-04 13:02:11 +02:00
johanleroy a7e04278fd release: git-arboretum 3.3.0 (« Démarrer le projet » : lancement multi-terminaux), vscode 0.4.0, desktop 0.1.3
CI / Build & test (Node 22) (push) Successful in 10m17s
CI / Build & test (Node 24) (push) Successful in 10m13s
CI / No em/en dashes (push) Successful in 4s
Deploy site (production) / build-and-deploy (push) Successful in 24s
Release / Publish to Gitea npm registry (push) Successful in 10m17s
VSCode Release / Package VSIX (push) Successful in 9m39s
Desktop Release / Build Linux (AppImage + deb) (push) Successful in 15m41s
CI / Pack & boot smoke (Node 22) (push) Successful in 10m3s
« Démarrer le projet » : un repo définit une fois ses commandes de démarrage
(serveur de dev, API, base de données), un clic ouvre un terminal PTY par
commande dans le dock IDE.

Serveur (additif, PROTOCOL_VERSION inchangé) :
- LaunchCommand[] persistées sur repos.launch_commands (migration 13) ; champ additif SessionSummary.launchRunId.
- POST /repos/:id/launch : résolution du worktree côté serveur, cwd de commande borné (anti-traversal), commandIds outrepasse enabled.
- GET /repos/:id/launch/detect : détection package.json / Procfile / docker-compose.
- Shell de login interactif ($SHELL -l -i, charge le PATH nvm/asdf) + auto-type de la commande ; le shell survit à la commande (échec visible).

Web : LaunchProjectModal + actions (ProjectTreeNode, SessionsPanel, CommandPalette), stores sessions/worktrees, i18n EN/FR.

Alignement du reste du projet :
- Extension VS Code 0.4.0 : commande Start Project (repo/worktree), Stop Launch, badge « launch » dans l'arbre, méthode REST startLaunch.
- Site vitrine : 16e feature card (Rocket) + section showcase « Start the project » (mockup fidèle au modal), i18n EN/FR.
- Documentation : README (EN + FR), help-content (EN + FR), CHANGELOGs server + vscode.

Vérifié : 430 tests, typecheck, build (web + site + vscode), acceptance-p13 ALL GREEN, VSIX packagé, garde anti-tirets, vérif visuelle du site (thèmes clair et sombre).
2026-07-21 13:54:16 +02:00
johanleroy 7a802e8920 release: git-arboretum 3.2.0 (refonte visuelle Emerald, thème clair/sombre, site & doc alignés)
CI / Build & test (Node 22) (push) Successful in 10m19s
CI / Build & test (Node 24) (push) Successful in 10m19s
CI / No em/en dashes (push) Successful in 6s
Deploy site (production) / build-and-deploy (push) Successful in 42s
Release / Publish to Gitea npm registry (push) Successful in 10m8s
CI / Pack & boot smoke (Node 22) (push) Successful in 10m0s
2026-07-20 22:49:51 +02:00
johanleroy adc53b413e feat(site,docs): aligne le site vitrine et la doc sur l'app « Emerald »
Site (packages/site) : adopte le design system Emerald (polices Inter +
JetBrains Mono variables, tokens sémantiques, thème clair/sombre + bascule)
et met les mockups à jour sur l'app réelle.

- style.css : tokens Emerald (@theme sombre + override html[data-theme=light]) ;
  lib/theme.ts + ThemeToggle.vue + anti-FOUC index.html ; sweep des couleurs
  brutes vers les tokens dans toutes les sections.
- Mockups fidèles à l'IDE multi-projet : HeroMockup (rail ActivityBar au lieu
  de la sidebar large + v obsolète retirée), ShowcaseSection (supervision au
  lieu du dashboard worktree-first, onglets mobiles réels), WorkspaceShowcase
  (diff-add/del, bouton commit accent-solid) ; framing « worktree-first »
  résiduel levé (i18n).
- og-cover.png rafraîchi (carte Emerald).

Docs : README.md + README.fr.md (retrait « Status: MVP », ajout du langage
Emerald + thème clair/sombre/système, VSIX 0.2.0 -> 0.3.0, section Screenshots),
vscode README (VSIX 0.3.0), brand README (thème clair), CHANGELOG daemon 3.2.0.
Captures IDE sombre + clair (brand/screenshot-ide-*.png).
2026-07-20 22:48:59 +02:00
johanleroy 008e976e01 release: git-arboretum 3.1.0 (IDE unique), desktop 0.1.1 (fix logo Debian)
CI / Build & test (Node 22) (push) Successful in 10m13s
CI / Build & test (Node 24) (push) Successful in 10m6s
CI / No em/en dashes (push) Successful in 3s
Release / Publish to Gitea npm registry (push) Successful in 9m55s
Desktop Release / Build Linux (AppImage + deb) (push) Successful in 14m9s
CI / Pack & boot smoke (Node 22) (push) Successful in 9m56s
2026-07-20 12:11:50 +02:00
johanleroy c7af406cbf release: IDE multi-projet + app native (git-arboretum 3.0.0, vscode 0.3.0, desktop 0.1.0)
CI / Build & test (Node 22) (push) Successful in 10m13s
CI / Build & test (Node 24) (push) Successful in 10m6s
CI / No em/en dashes (push) Successful in 3s
VSCode Release / Package VSIX (push) Successful in 9m38s
CI / Pack & boot smoke (Node 22) (push) Successful in 9m56s
Desktop Release / Build Linux (AppImage + deb) (push) Failing after 6m11s
Daemon 3.0.0 : marque le cap « IDE IA multi-projet + app de bureau native » (refonte additive, PROTOCOL_VERSION inchangé ; le tarball embarque la nouvelle SPA IDE + le handshake token desktop). Extension VS Code 0.3.0 : deep-link « Open Worktree IDE » vers l'IDE multi-projet, encodage wt-key unifié via @arboretum/shared (CHANGELOG + README à jour). Paquet desktop 0.1.0 (première release).

package.json ET package-lock.json bumpés (npm ci strict). 431 tests, 0 tiret, builds daemon/web/vscode/site verts.
2026-07-17 18:31:37 +02:00
johanleroy de066abb54 feat(server): handshake token pour un shell embarquant le daemon (app de bureau)
CI / Build & test (Node 24) (push) Has been cancelled
CI / Pack & boot smoke (Node 22) (push) Has been cancelled
CI / No em/en dashes (push) Has been cancelled
CI / Build & test (Node 22) (push) Has been cancelled
Dans runDaemon, si ARBORETUM_EMIT_TOKEN_FD est fourni, mint un token 'desktop' et l'écrit en JSON {token,url} sur ce descripteur (pipe stdio privé parent-enfant). Additif et gardé : sans la variable, comportement strictement inchangé. Permettra à l'app Electron d'ouvrir la SPA déjà authentifiée sans écran de login. Vérifié (handshake OK), 431 tests.
2026-07-17 17:44:36 +02:00
johanleroy 65ef616867 chore(typo): retire tous les tirets cadratins/demi-cadratins + garde CI
CI / Build & test (Node 24) (push) Has been cancelled
CI / Pack & boot smoke (Node 22) (push) Has been cancelled
CI / No em/en dashes (push) Has been cancelled
CI / Build & test (Node 22) (push) Has been cancelled
Deploy site (production) / build-and-deploy (push) Successful in 20s
Remplace les 547 tirets cadratins (U+2014) et demi-cadratins (U+2013) des fichiers versionnés par la ponctuation contextuelle adaptée (point médian, deux-points, virgule, parenthèses ; tiret simple pour les plages), sur 122 fichiers (appli, vitrine, doc, tests, workflows, scripts).

Ajoute le job CI « lint-dashes » (git grep -P) qui échoue si un tiret cadratin/demi-cadratin réapparaît, hors logo binaire et captures brutes du terminal (fidélité des fixtures de détection de dialogue).
2026-07-17 16:44:00 +02:00
johanleroy 985531a986 release: git-arboretum 2.0.0
CI / Build & test (Node 22) (push) Successful in 10m10s
CI / Build & test (Node 24) (push) Successful in 10m6s
Deploy site (production) / build-and-deploy (push) Successful in 17s
Release / Publish to Gitea npm registry (push) Successful in 10m1s
VSCode Release / Package VSIX (push) Successful in 9m41s
CI / Pack & boot smoke (Node 22) (push) Successful in 9m58s
Refonte « vrai IDE IA worktree » (P7→P12) : additif et rétrocompatible
(PROTOCOL_VERSION inchangé), majeure pour marquer le cap produit.
2026-06-27 16:04:37 +02:00
johanleroy 08695a707d feat(p12a): services git distants (PAT/app_password) + clone HTTPS
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).
2026-06-27 14:27:18 +02:00
johanleroy e8d10b7ec0 feat(p11): temps réel complet (watcher checkout principal + topic settings)
P11-A — branche du checkout principal modifiée hors Arboretum :
- fs-watcher: pin « permanent » non évinçable (pinRepo/unpinRepo, repoPins dans evictIfNeeded)
- worktree-manager: armMainCheckoutWatchers() + arm/désarm sur addRepo/découverte/removeRepo/hidden
- index.ts: armMainCheckoutWatchers() dans runDaemon → git checkout CLI sur le principal → worktree_update <500ms sans watch client

P11-B — réglages en temps réel :
- protocole additif: type SettingsBroadcast (source unique, réutilisé par SettingsResponse), topic 'settings', message settings_update (validés parseClientMessage + gateway)
- core/settings-bus.ts (EventEmitter) ; routes/settings émet après PATCH ; gateway relaie aux abonnés 'settings'
- web: ws-client subscribeSettings + routage ; store settings applySettings/startRealtime ; AppShell abonne globalement ; SettingsView re-sync des drafts scalaires sans écraser une saisie en cours
- tests: protocol (topic settings) + fs-watcher (pinRepo non évincé) ; acceptance-p11.mjs (checkout principal <500ms + settings_update)
2026-06-27 14:08:44 +02:00
johanleroy 92670a796a feat(p9): commit/push avancé dans l'IDE (staging sélectif, discard, amend, fetch/pull)
- components/workspace/CommitPanel.vue : staging sélectif par fichier (stage/unstage/stage all/unstage all), discard avec confirmation (includeUntracked), zone de commit (message + amend), commit mode 'staged', push, fetch, pull --ff-only (rebase proposé en cas de divergence), gestion 409 ALREADY_PUSHED
- components/workspace/FileRow.vue : ligne de fichier réutilisable (badge statut M/A/D/?/U + clic → diff + slot actions)
- WorkspaceView : CommitPanel remplace ChangedFilesPanel ; @changed → reload des changements
- stores/worktrees : applyWorktree (upsert depuis les mutations git → header live)
- i18n EN+FR (commit.*) ; acceptance-p9.mjs (staging sélectif, amend OK/409, pull ff-only OK + divergence refusée)
2026-06-27 13:53:05 +02:00
johanleroy 75efecf93f feat(p8): vue IDE /workspace (arbre + Monaco + diff + terminal)
- backend: garde-fou conflit d'édition par mtime (GET renvoie mtime, PUT refuse en 409 STALE_FILE si baseMtime périmé)
- lib: wt-key (base64url du chemin worktree), diff-parse (parseur pur du diff unifié → hunks)
- composables: useMonaco (import dynamique → chunk isolé), useWorkspaceLayout (largeurs/panneau persistés)
- components/workspace: GitStatusBadge, FileTree+FileTreeNode (lazy fs/list includeFiles), ChangedFilesPanel, DiffViewer (coloration +/-), MonacoEditor (Ctrl+S + bannière conflit reload/overwrite)
- views/WorkspaceView: 3 colonnes desktop redimensionnables + SegmentedControl mobile, header live (GitStatusBadge), watchWorktree → refresh diff/changements, terminal de la session corrélée
- router meta 'ide' + route /workspace/:repoId/:wt ; App.vue plein écran sans AppShell ; WorktreeCard bouton « Ouvrir l'IDE »
- deps: monaco-editor (lazy, vendor-monaco isolé, 0 impact bundle initial) ; vite manualChunks
- i18n EN+FR (workspace/editor/diff/git) ; tests diff-parse + wt-key ; acceptance-p8.mjs (mtime/409 + diff)
2026-06-27 13:47:10 +02:00
johanleroy c8dd539571 feat(p10): archivage automatique des sessions terminées (rétention configurable)
- DB: migration #10 (sessions.archived_at + index), helpers archive/unarchive/archiveExpired (soft-archive, jamais de DELETE)
- core/retention-settings.ts: session_retention_days (défaut 30, 0=jamais, 1-3650) + session_purge_days (off)
- core/session-archive.ts: scheduler start/stop/sweep (calqué DiscoveryService), câblé dans runDaemon
- pty-manager.list({includeArchived}) + SessionSummary.archived + emitHistoricalUpdate
- routes: GET /sessions?includeArchived, POST/DELETE /sessions/:id/archive, POST /sessions/archive-now
- protocole additif: message WS session_archived (relayé par la gateway, abonnés 'sessions')
- settings: retentionDays/purgeDays exposés et validés dans PATCH /settings
- web: store sessions (showArchived + archive/unarchive), SessionsListView (toggle/badge/actions), SettingsView (slider rétention), i18n EN+FR
- tests: retention-settings + session-archive (vitest) + settings-routes étendu ; acceptance-p10.mjs (sweep, event WS, resume d'une session archivée → 201, rétention=0)
2026-06-27 13:31:28 +02:00
johanleroy be43911dc0 feat(p7): moteur git détaillé, API fichiers et watcher FS temps réel
Fondations de la refonte « vrai IDE IA worktree » (chantier P7→P12).

- git.ts : listChanges (status --porcelain=v2 -z + --numstat fusionnés),
  fileDiff (diff unifié borné, refus binaire, untracked via --no-index),
  stage/unstage/restore/clean, commitStaged, amendCommit (refus si poussé),
  fetchRemote, pull (ff-only|rebase), lastCommit, resolveGitDir,
  isSafeRelativePath ; worktreeStatus enrichi (compteurs staged/unstaged/
  conflict + dernier commit), champs additifs WorktreeGitStatus.
- core/fs-watcher.ts : FsWatcherService (chokidar, refcount + pool LRU borné,
  ignore .git sauf HEAD/index, débounce) → invalide factsCache, rediffuse
  worktree_update et émet worktree_changes.
- WorktreeManager : getWorktreeChanges/getFileDiff/stage/unstage/discard/
  fetch/pull/watch/unwatch/assertPathInWorktree ; commitWorktree { mode, amend }.
- routes/git.ts (changes/diff/stage/unstage/discard/fetch/pull) et
  routes/files.ts (GET/PUT contenu fichier, bornage strict au worktree) ;
  fs/list?includeFiles=1 (flag isFile).
- protocole ADDITIF (PROTOCOL_VERSION inchangé) : messages WS watch/unwatch
  (validés dans parseClientMessage) + worktree_changes poussé ciblé par la
  gateway ; front wsClient.watchWorktree + lib/git-api.ts + api.put.
- tests git/fs-watcher/protocole + acceptance-p7.mjs (ALL GREEN).
- dépendance : chokidar (serveur).
2026-06-27 12:15:00 +02:00
johanleroy a67871b9b9 release: @johanleroy/git-arboretum 1.11.0
Release / Publish to Gitea npm registry (push) Successful in 9m52s
2026-06-24 10:28:28 +02:00
johanleroy b5236b41c8 feat(settings): réglages Claude CLI (binaire + ~/.claude) & notif « disponible »
- Réglages → Claude CLI : override du chemin du binaire `claude` (effet à la
  prochaine session, fallback `which claude`), diagnostic de détection, et
  override de la racine ~/.claude (effet au redémarrage). Validateurs stricts.
- Push : notifie aussi sur le front busy→idle (session redevenue disponible).
- Renomme l'état affiché idle → « disponible » / « available » (web EN/FR + VS Code) ;
  l'enum SessionActivity du protocole reste inchangé.
2026-06-24 10:15:29 +02:00
johanleroy 2506dfb1f3 fix(cli): figer le PATH d'installation dans l'unit systemd / plist launchd
Un service systemd user / LaunchAgent démarre avec un PATH minimal qui n'inclut
pas ~/.local/bin (où vit le binaire `claude`) → resolveClaudeBin (`which claude`)
échouait avec « Claude Code CLI not found in PATH ». `arboretum install` fige
désormais le PATH de l'environnement d'installation dans l'unit/plist.
2026-06-24 10:15:29 +02:00
johanleroy 7d618c30d5 release: @johanleroy/git-arboretum 1.10.0
CI / Build & test (Node 22) (push) Successful in 10m6s
CI / Build & test (Node 24) (push) Successful in 9m58s
Deploy site (production) / build-and-deploy (push) Successful in 15s
Release / Publish to Gitea npm registry (push) Successful in 9m51s
CI / Pack & boot smoke (Node 22) (push) Successful in 9m50s
2026-06-23 18:52:39 +02:00
johanleroy 8b9060e0c0 feat: création de projet (nouveau dossier + session) & en-tête de session enrichi
- POST /api/v1/projects : crée <root>/<name> (mkdir non récursif, 409 si existant),
  git init optionnel, puis lance une session dedans. Anti-traversal sur le nom (core/project.ts).
- Web : NewProjectModal (racine préremplie scanRoots[0], case git init) + bouton dans SessionsListView.
- SessionContextBar : badge du groupe (cliquable) + repos couverts avec leur branche dans l'en-tête
  de session ; session simple = repo+branche déduits du cwd.
- 14 tests (unitaires + route).
2026-06-23 18:52:22 +02:00
johanleroy a1fd00b046 release: @johanleroy/git-arboretum 1.9.0
CI / Build & test (Node 24) (push) Has been cancelled
CI / Pack & boot smoke (Node 22) (push) Has been cancelled
CI / Build & test (Node 22) (push) Has been cancelled
VSCode Release / Package VSIX (push) Has been cancelled
Deploy site (production) / build-and-deploy (push) Successful in 17s
Release / Publish to Gitea npm registry (push) Successful in 9m53s
2026-06-23 17:43:48 +02:00
johanleroy 663ae7ace1 fix: recherche worktrees, sessions externes masquées, rendu/historique terminal & plein écran grille
- Recherche : le watcher débouncé du singleton useWorktreeView est créé dans un effectScope
  détaché → ne gèle plus après une navigation ; recherche aussi par label de dépôt ; accès à
  la palette depuis le MoreSheet mobile (sidebar/⌘K indisponibles sur mobile).
- Sessions : sessionsForCwd exclut désormais toujours les sessions masquées ; les sessions
  externes (discovered) sont masquées par défaut côté UI, avec puce de révélation par carte et
  case globale dans le dashboard.
- Terminal : ACK découplé du callback de rendu (armé à la réception + flush au retour de
  visibilité) → plus de pause PTY quand l'onglet passe en arrière-plan ; repaint forcé sur
  perte de contexte WebGL / resize / retour en avant-plan. Historique élargi : REPLAY_TAIL_BYTES
  1 Mo, RING_CAPACITY 4 Mo, scrollback xterm 20k.
- Grille de groupe : bouton « plein écran » sur chaque cellule ouvrant /sessions/:id.
2026-06-23 17:42:49 +02:00
johanleroy 5ebe3a0f37 release: @johanleroy/git-arboretum 1.8.0
CI / Build & test (Node 22) (push) Successful in 10m0s
CI / Build & test (Node 24) (push) Successful in 9m54s
Deploy site (production) / build-and-deploy (push) Successful in 16s
Release / Publish to Gitea npm registry (push) Successful in 9m46s
CI / Pack & boot smoke (Node 22) (push) Successful in 9m45s
2026-06-22 19:55:52 +02:00
johanleroy f4fb6c3b52 feat(worktrees): création intelligente (auto) + commit/push/promotion + grille agrandissable
- addWorktree résout la branche par dépôt (branchExists) : checkout si présente, suivi de origin/<b> si seulement remote, sinon création (-b) depuis la branche par défaut. Corrige le 'fatal: invalid reference' sur les groupes hétérogènes ; newBranch -> mode (déprécié, mappé en route).
- Nouvelles opérations git : commit (add -A), push (upstream auto), promotion « en principal » (la branche du worktree devient le checkout principal, sans merge ni conflit, ancienne branche conservée). Routes /worktrees/{commit,push,promote} auditées + GET /repos/:id/branches.
- Web : actions Commit/Push/Promouvoir sur WorktreeCard, sélecteur de branche de base (datalist) dans RepoSection et GroupSessionModal, agrandissement d'un terminal au choix dans TerminalGrid.
- Court-circuite la session de groupe quand aucun worktree n'a pu être créé (fini le masquage par « no resolvable worktree »).
- Tests : git.ts (branchExists/listBranches/commitAll/auto), worktree-manager (commit/promote/branches) ; acceptance P5 étend le scénario worktree de groupe sur branche neuve + commit + promotion.
2026-06-22 19:55:45 +02:00
johanleroy e84c6a7f6d release: @johanleroy/git-arboretum 1.7.0
CI / Build & test (Node 22) (push) Successful in 10m0s
CI / Build & test (Node 24) (push) Successful in 9m53s
Deploy site (production) / build-and-deploy (push) Successful in 16s
Release / Publish to Gitea npm registry (push) Successful in 9m46s
CI / Pack & boot smoke (Node 22) (push) Successful in 9m50s
2026-06-22 16:03:11 +02:00
johanleroy dacff2b98f feat(sessions): masquer les sessions externes + terminal plein écran
Masquage persistant des sessions Claude découvertes (lancées hors Arboretum)
qui polluent la liste — calqué sur repos.hidden :
- table hidden_sessions (#9) clé claudeSessionId ; helpers DB
- DiscoveryService pose le champ additif SessionSummary.hidden (resume/fork
  restent possibles, survit à un re-scan)
- routes POST/DELETE /sessions/:id/hide, POST /sessions/hide-discovered
  (masse, un clic), GET /sessions?includeHidden=true
- UI : bouton Masquer par ligne, « Masquer l'historique externe », toggle
  « Afficher les masquées », badge masquée ; store + i18n EN/FR + audit

Terminal plein écran (corrige le sizing) :
- SessionView root s'étire (flex-1) → xterm calcule les bonnes dimensions
- refit robuste (requestAnimationFrame + après resync), h-full sur le wrapper
- bouton plein écran (API Fullscreen), tabbar mobile masquée en fullbleed

DialogPrompt : options en liste verticale pleine largeur (plus de troncature
ni de chevauchement sur les libellés longs / multi-lignes).

Doc : centre d'aide (sessions), README EN/FR, site (showcase), CLAUDE.md.
Tests : discovery (hidden) + route hide/unhide/hide-discovered.
2026-06-22 16:02:27 +02:00
johanleroy bf9c6ba8f3 release: @johanleroy/git-arboretum 1.6.1
CI / Build & test (Node 22) (push) Successful in 10m0s
CI / Build & test (Node 24) (push) Successful in 9m54s
Deploy site (production) / build-and-deploy (push) Successful in 16s
Release / Publish to Gitea npm registry (push) Successful in 9m46s
CI / Pack & boot smoke (Node 22) (push) Successful in 9m45s
2026-06-22 14:41:36 +02:00
johanleroy 1b57c3801c feat(groups): session de groupe au parent commun + redirection vers le terminal
Le cwd d'une session de groupe devient le PARENT COMMUN des répertoires
couverts (racine neutre, chemins relatifs cross-repo naturels) au lieu du
premier repo arbitraire ; chaque repo reste relié en --add-dir. Garde-fou :
si le parent commun est la racine du FS, on retombe sur le premier répertoire.
Nouveau module pur resolveGroupCwd (core/group-session.ts). Côté web, un
lancement réussi redirige vers le terminal plein écran de la session, avec
un toast (succès ou couverture partielle).
2026-06-22 14:41:15 +02:00
johanleroy 4e3b1f5604 fix(sessions): reprendre/forker une session managée morte par UUID (résout le 404)
Le bouton « Reprendre » envoie l'UUID Arboretum, mais resume/fork ne
résolvaient l'id que via la découverte (indexée par claudeSessionId, qui
exclut justement les sessions managées) → 404 systématique après fermeture.
Ajoute PtyManager.resumeTargetById (cwd d'origine + claudeSessionId + groupe
lus en DB par UUID) et un résolveur unifié dans resume ET fork : session
managée morte par UUID, sinon session claude externe découverte par
claudeSessionId. Garde-fous anti-resume d'une session vivante conservés.
2026-06-22 14:41:06 +02:00
johanleroy 8036de2f0d release: @johanleroy/git-arboretum 1.6.0
CI / Build & test (Node 22) (push) Successful in 9m59s
CI / Build & test (Node 24) (push) Successful in 9m54s
Deploy site (production) / build-and-deploy (push) Successful in 21s
Release / Publish to Gitea npm registry (push) Successful in 9m49s
CI / Pack & boot smoke (Node 22) (push) Successful in 9m45s
2026-06-22 11:30:54 +02:00
johanleroy 915fdf185d feat(worktrees): démarrer une session sur la branche principale ou tout worktree
Ajoute le choix « créer un worktree OU bosser sur la branche principale » au
moment de démarrer le travail, sur deux surfaces :
- bouton « Démarrer » (claude/bash) sur chaque WorktreeCard, y compris le
  checkout principal (badge « principal ») — comblait un manque : impossible
  jusqu'ici de lancer une session sur un worktree existant depuis le dashboard ;
- toggle de mode (Worktree / Branche principale) dans le formulaire d'entête
  de RepoSection.

Option git « créer & basculer » : nouvel endpoint POST /api/v1/repos/:id/session
qui lance UNE session dans le checkout principal (repo.path), avec création ou
bascule de branche optionnelle (git switch[-c]) — refusée en 409 si l'arbre est
sale. Pas de hooks ni de pré-trust (c'est le dépôt réel de l'utilisateur).

- shared : type additif StartRepoSessionRequest.
- server : git.switchBranch + WorktreeManager.startMainSession + route.
- web : store worktrees.startMainSession, UI WorktreeCard/RepoSection, i18n fr/en.
- tests : +5 unitaires (switchBranch, startMainSession) ; acceptance-p3 étendue.
2026-06-22 11:30:40 +02:00
johanleroy 4e1c5b2c33 release: @johanleroy/git-arboretum 1.5.0 2026-06-22 10:08:30 +02:00
johanleroy c6ea9f7930 feat(groups): session Claude unique par groupe via --add-dir (P6)
Deploy site (production) / build-and-deploy (push) Successful in 21s
Un groupe lance désormais UNE seule session Claude couvrant tous ses
repos/worktrees (--add-dir) au lieu d'une session par repo, pour
travailler en simultané dans une conversation partagée. Le transport WS,
le flow control et l'attach sont inchangés (toujours 1 session, 1 channel).

- shared: SessionSummary.addedDirs/groupId (champs additifs optionnels) ;
  CreateGroupSessionRequest / GroupSessionResponse.
- server: --add-dir dans claude-launcher ; spawn({addDirs,groupId}) +
  persistance (migration #8 : sessions.added_dirs/group_id) ;
  POST /api/v1/groups/:id/session (résolution des dirs cote serveur) ;
  resume re-relie les dirs ; deleteGroup nullifie group_id.
- web: GroupSessionModal (modes feature / checkouts principaux) ;
  createGroupFeature/createGroupSession ; badge « groupe · N depots » ;
  sessionsInGroup dedupliquee.
- site: textes EN/FR « une seule session Claude » + diagramme hub.
- tests: claude-launcher, pty-manager (groupe), group-manager ;
  acceptation P5 etendue (session de groupe multi-repo). 272 tests verts.
2026-06-22 10:06:23 +02:00
johanleroy 8d3a47bd91 release: @johanleroy/git-arboretum 1.4.1
Release / Publish to Gitea npm registry (push) Has been cancelled
Première version avec le tarball autonome (shared inliné dans dist/_shared).
Le 1.4.0 du registre a pu être publié sans @arboretum/shared embarqué
(bundleDependencies d'un workspace instable en CI/root) ; 1.4.1 garantit un
paquet installable et démarrable par n'importe quel consommateur.
2026-06-19 09:49:07 +02:00
johanleroy 073f2cf9ca fix(packaging): inline @arboretum/shared dans dist/ — tarball autonome (abandon de bundleDependencies)
bundleDependencies d'un paquet *workspace* est instable selon l'environnement npm
(mode -w, exécution en root sur un runner CI) : npm voyait shared comme un lien
workspace et n'embarquait AUCUN fichier ("bundled files: 0"), publiant un tarball
cassé — `Cannot find module '@arboretum/shared'` au démarrage chez le consommateur.
C'est ce que détectait (à juste titre) le job pack-smoke.

Nouveau mécanisme, identique sur tout environnement : scripts/inline-shared.mjs
(hook prepack) copie le JS compilé de shared dans dist/_shared/ et réécrit l'import
bare '@arboretum/shared' des .js du serveur vers ce chemin relatif. shared passe en
devDependency (résolu en dev via le symlink workspace, jamais exigé du consommateur).
Plus de node_modules embarqué ni de symlink dans le tarball.

ci.yml (pack-smoke) packe désormais en -w (comme release.yml) et asserte l'autonomie
(dist/_shared présent + zéro import bare) avant le boot smoke.

Validé de bout en bout sur checkout propre : npm ci + build + pack -w + install dans
projet vierge + boot -> HTTP 401, et 263 tests verts.
2026-06-19 09:46:05 +02:00
johanleroy 813dfd952c release: @johanleroy/git-arboretum 1.4.0
Release / Publish to Gitea npm registry (push) Has been cancelled
2026-06-18 17:03:09 +02:00
johanleroy 693e6736de feat(web): lien « Buy me a coffee » (nav, réglages, funding)
- constante BUYMEACOFFEE_URL ; item de nav « Offrez-moi un café »
- section support dans les Réglages + i18n EN/FR
- champ `funding` dans le package.json publié ; mentions README EN/FR
2026-06-18 17:02:30 +02:00
johanleroy 33295a7aaf feat: clean install (Gitea en dur, scan off) + durcissement sécurité entreprise
Gitea
- lien « Code source » hardcodé (REPO_SOURCE_URL) vers le dépôt, toujours visible
- retrait complet du réglage configurable (api.ts, route+store settings, SettingsView, i18n, help, tests)

Découverte des dépôts
- aucune racine de scan par défaut → pas de scan au premier démarrage (clean install)
- corrige la découverte des dépôts à l'INTÉRIEUR d'une racine qui est elle-même un repo
  (depth 0 = conteneur de scan, on descend ; depth > 0 = feuille)

Sécurité « enterprise-deployable »
- en-têtes HTTP durcis (CSP, X-Frame-Options, nosniff, Referrer-Policy, HSTS conditionnel, no-store API), header Server retiré
- permissions DB 0o600 / dossier de données 0o700 ; error handler sanitisé ; garde Content-Type sur les mutations
- chiffrement au repos AES-256-GCM des secrets (server_secret, clé privée VAPID) via SecretBox
- journal d'audit (migration #7) + endpoint /audit-logs + RGPD export/effacement + UI Réglages
- SECURITY.md, docs/ENTERPRISE_DEPLOYMENT.md, sections README EN/FR, SBOM CycloneDX en CI

CI
- pack-smoke packe depuis le contexte du package (cd packages/server) au lieu de « npm pack -w » :
  corrige l'embarquement de @arboretum/shared dans le tarball

Purge des données personnelles du dépôt public
- suppression de spikes/s4-discovery/result.json, reformulation du VERDICT
- chemin de test générique, anonymisation des 5 fixtures de dialogues
2026-06-18 16:44:25 +02:00
johanleroy 755cba6b78 release: @johanleroy/git-arboretum 1.3.0
Release / Publish to Gitea npm registry (push) Has been cancelled
2026-06-18 14:46:03 +02:00
johanleroy fe2a3e66c7 feat: découverte automatique des dépôts git (scan + montrer/cacher)
Scan borné du système de fichiers (racines configurables, défaut home ; profondeur/nombre/timeout bornés ; symlinks non suivis ; exclusions node_modules/dotdirs) qui auto-enregistre les nouveaux dépôts. Insertion atomique ON CONFLICT DO NOTHING (idempotence + anti-résurrection d'un dépôt masqué + anti-course). Scan au démarrage + bouton manuel + re-scan périodique (RepoDiscoveryService, démarré dans runDaemon). Colonne repos.hidden : masquer = conservé en DB mais exclu du dashboard et jamais ré-ajouté ; supprimer = re-découvrable. UI : bouton œil par dépôt + bascule afficher-les-masqués sur le dashboard, section Découverte dans les Réglages (racines + intervalle, allow-list stricte). Robustesse : listAllWorktrees tolère l'échec git par dépôt ; flag --no-discover (escape hatch + hermétisme des acceptations).
2026-06-18 14:45:12 +02:00
johanleroy b070b74929 chore(deps): @fastify/static ^8 → ^9
Mise à niveau majeure du plugin de service statique (déjà installée dans l'arbre de travail, build + 253 tests verts).
2026-06-18 14:44:52 +02:00
johanleroy c9670ca309 feat: onglets Réglages & Aide + icône Gitea
Réglages : préférences (langue, notifications push + test), gestion complète des tokens d'accès (liste/création/révocation, garde anti lock-out sur le dernier token), URL Gitea configurable, infos serveur en lecture seule (port/bind/origines/VAPID + flags CLI). Aide : documentation bilingue EN/FR de toutes les fonctionnalités, avec recherche. Icône Gitea (lien externe) dans la nav (sidebar + MoreSheet mobile).

Backend : routes /api/v1/auth/tokens (GET/POST/DELETE) + tokenId dans /me ; routes/settings.ts (GET/PATCH, allow-list stricte gitea_url, aucun secret exposé, URL validée http/https anti-XSS) ; AuthService.listTokens/revokeToken (transaction). Front : NavItem gère les liens externes, nav primaire/secondaire, store settings, vues SettingsView/HelpView.

236 tests verts (+15 nouveaux : auth-tokens, settings-routes).
2026-06-18 14:16:53 +02:00