f513cff253
feat: groupes de travail (P5)
...
Ajoute la notion de groupe — collection nommée de repos (membership légère
persistée, many-to-many) — pour piloter plusieurs repos en simultané :
- DB : migration #5 (tables groups + group_repos, FK ON DELETE CASCADE).
- GroupManager (synchrone, EventEmitter) + routes REST /api/v1/groups ;
ne persiste que la membership, worktrees/sessions filtrés par repoId côté client.
- Protocole : GroupSummary, DTOs, topic WS « groups », events group_update/removed
(additifs, PROTOCOL_VERSION inchangé).
- Web : store groups, GroupsListView, GroupView (réutilise RepoSection),
grille multi-terminaux (TerminalGrid/TerminalCell), action « feature cross-repo »
(orchestration client, tolérante aux échecs partiels), routes + i18n EN/FR.
- Tests : group-manager.test.ts + extension protocol.test.ts ; acceptance-p5.mjs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-18 10:03:19 +02:00
7de2da7469
feat(web): sélecteur de répertoire (parcourir au lieu de taper le chemin)
...
Ajoute un navigateur de dossiers réutilisable sur les deux champs qui
exigeaient un chemin absolu tapé à la main : « Répertoire de travail »
(nouvelle session) et « Chemin du dépôt » (ajout de repo). Un bouton
« Parcourir… » déplie un panneau inline ; le champ texte reste pour
taper/coller un chemin connu. Pour l'ajout de repo, les sous-dossiers
qui sont des dépôts git sont signalés par un badge.
Serveur : nouvel endpoint GET /api/v1/fs/list (authentifié par le hook
preValidation global), ne renvoie que des noms de sous-dossiers (jamais
de contenu de fichier). Valide le chemin via resolve() (clampe à la
racine, neutralise « .. »), masque les dotfiles par défaut (showHidden),
annote les dépôts git (markRepos), tolère les entrées illisibles.
Tests : packages/server/test/fs-routes.test.ts (10 cas — listing, tri,
hidden, markRepos, rejets 400/404, auth 401). Suite : 185/185 verts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-17 13:04:10 +02:00
47423c0651
P4-B: notifications Web Push (VAPID) sur passage en waiting
...
- db: migration id=4 `push_subscriptions` (liées au token d'auth) ; clés VAPID en settings
- PushService: bootstrap idempotent des clés VAPID, subscribe/unsubscribe/count,
notify() best-effort (purge des abonnements 410/404 Gone) ; sender injectable pour les tests
- routes/push.ts: GET vapid-public-key, POST subscribe/unsubscribe/test (toutes sous auth globale)
- pty-manager: déclencheur push sur FRONT MONTANT vers waiting, débouncé 1500ms et annulable
(faux positif ignoré) ; câblage app/index/config (--vapid-contact)
- shared/api.ts: types VapidKeyResponse / PushSubscribeRequest / PushUnsubscribeRequest
- deps: web-push (+ @types/web-push) côté serveur
- tests: push-service (idempotence, UPSERT, 410-purge, payload) + trigger pty-manager (169 verts)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-15 12:13:56 +02:00
acd920ebcd
P3-A: worktrees multi-repo & cycle de vie (backend)
...
Enregistrement de repos et gestion de leurs worktrees git, source de vérité
= git (worktrees dérivés + cache court par repo), corrélation worktree ↔
sessions par cwd, mutations sérialisées par repo.
- shared: RepoSummary, PostCreateHook, WorktreeSummary, WorktreeGitStatus ;
messages WS repo_update/worktree_update/*_removed ; topic sub 'worktrees'
(+ parseClientMessage) ; DTOs REST repos/worktrees.
- db: migration id:3 (table repos).
- core/git.ts: couche git sûre (execFile, jamais de shell, -- avant chemins,
GIT_OPTIONAL_LOCKS=0), parseWorktreePorcelain, list/add/remove/prune/status/
ahead-behind, validation branche + chemin.
- core/claude-trust.ts: pré-trust atomique de ~/.claude.json (spike S3).
- core/worktree-manager.ts: repos CRUD, create (worktree add + pré-trust +
hooks post-create + startSession optionnel), adopt, delete (garde-fous 409
dirty / 400 main / 409 session live), prune ; events.
- routes/repos.ts + routes/worktrees.ts, câblage app.ts, gateway topic worktrees.
- tests: git (repos tmp réels), claude-trust, worktree-manager (146 verts).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-12 18:31:06 +02:00
fb175bc7c5
P2: découverte & reprise des sessions Claude
...
Arboretum découvre désormais toutes les sessions Claude de la machine
(scan ~/.claude/projects + registre ~/.claude/sessions), distingue
vivantes/mortes par pid+procStart, et permet de reprendre une morte
(--resume dans son cwd d'origine) ou forker une vivante sans la corrompre.
- shared: SessionSummary enrichi (source, claudeSessionId, pid, resumable,
attachable, registryStatus) — additif, PROTOCOL_VERSION inchangé ;
types REST resume/fork.
- db: migration id:2 (claude_session_id, resumed_from).
- core: jsonl-discovery (parseur tolérant, scan asynchrone non bloquant),
session-registry (vivacité pid+procStart), discovery-service (cache +
refresh périodique + diff/broadcast), pty-manager (resume/fork + capture
du claudeSessionId via le registre).
- routes: /sessions/:id/resume (garde-fou 409 anti-corruption sur session
vivante) et /fork ; GET fusionné managées + découvertes ; relais WS.
- web: badges managed/discovered + busy/idle/waiting, actions conditionnelles
(Open/Observe/Kill vs Fork/View vs Resume/Fork), vue read-only des sessions
externes, i18n EN/FR.
- tests: jsonl-discovery, session-registry, discovery-service + resume/fork
(130 verts) ; acceptation E2E acceptance-p2.mjs (sans quota) ALL GREEN.
Conforme aux verdicts S1 (resume dans cwd d'origine, vivacité pid+procStart)
et S4 (munge cwd, parseur tête+queue, priorité de titre).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-12 18:20:21 +02:00
3a1396036e
P1 spine: monorepo, shared WS protocol, server daemon
...
- npm workspaces (shared / server / web), TS strict, project refs
- @arboretum/shared: multiplexed WS protocol (JSON control + binary
output frames: 1B type + u32le channel), flow-control constants
(ACK 256K, HIGH 384K, LOW 128K, lagging 2M), REST types
- git-arboretum server: Fastify 5 + node:sqlite (single native dep:
node-pty prebuilt), token auth (sha256 at rest, HMAC cookie, global
login rate limit + backoff), strict Origin check on /api and /ws,
PtyManager (2MiB ring with monotonic offset, resync replay = reset +
256KiB tail, pause/resume only when ALL interactive clients exceed
HIGH, observers never throttle, lagging clients resync), WS gateway
(attach/stdin/resize/ack, heartbeat 30s), SIGTERM→SIGKILL 5s grace
- CLI: arboretum [--port 7317] [--bind 127.0.0.1] — non-loopback bind
requires an explicit safety flag
- Smoke-tested: login/401/403-origin/spawn bash/kill/grace-SIGKILL all
green
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-06-11 22:04:09 +02:00