Files
arboretum/packages/server/src/core/group-session.ts
Johan LEROY 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

38 lines
1.8 KiB
TypeScript

import { parse, resolve, sep } from 'node:path';
/**
* Plus long ancêtre commun d'un ensemble de chemins absolus (par segments, jamais par préfixe
* de chaîne — `/a/bc` n'est PAS un ancêtre de `/a/bcd`). Pour un seul chemin, renvoie ce chemin.
*/
export function commonAncestorDir(paths: string[]): string {
const first = paths[0];
if (first === undefined) throw new Error('commonAncestorDir: empty input');
const firstSegs = resolve(first).split(sep);
let common = firstSegs.length;
for (let i = 1; i < paths.length; i++) {
const segs = resolve(paths[i]!).split(sep);
let k = 0;
while (k < common && k < segs.length && segs[k] === firstSegs[k]) k++;
common = k;
}
const joined = firstSegs.slice(0, common).join(sep);
// `['', 'a', 'b'].slice(0,1).join('/')` === '' → racine POSIX ; rétablir le séparateur racine.
return joined === '' ? parse(resolve(first)).root : joined;
}
/**
* Politique de répertoire de travail d'une session de groupe (P6) : le `cwd` est le PARENT COMMUN
* des répertoires couverts (racine neutre, chemins relatifs cross-repo naturels), chaque répertoire
* étant ensuite relié via `--add-dir` (le dédoublonnage + filtrage du cwd est fait par `PtyManager`).
* Garde-fou : si le parent commun est la racine du FS (repos éparpillés sur des racines différentes),
* on retombe sur le premier répertoire pour ne pas accorder à Claude la permission sur tout le disque.
*/
export function resolveGroupCwd(dirs: string[]): { cwd: string; addDirs: string[] } {
const first = dirs[0];
if (first === undefined) throw new Error('resolveGroupCwd: empty input');
const ancestor = commonAncestorDir(dirs);
const root = parse(resolve(first)).root;
const cwd = ancestor === root ? first : ancestor;
return { cwd, addDirs: dirs };
}