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>
149 lines
3.9 KiB
TypeScript
149 lines
3.9 KiB
TypeScript
// Types REST partagés (préfixe /api/v1).
|
|
import type { GroupSummary, PostCreateHook, RepoSummary, SessionSummary, WorktreeSummary } from './protocol.js';
|
|
|
|
export interface ApiError {
|
|
error: { code: string; message: string; details?: unknown };
|
|
}
|
|
|
|
export interface LoginRequest {
|
|
token: string;
|
|
}
|
|
export interface LoginResponse {
|
|
ok: true;
|
|
label: string;
|
|
}
|
|
export interface MeResponse {
|
|
ok: true;
|
|
tokenLabel: string;
|
|
serverVersion: string;
|
|
}
|
|
|
|
export interface CreateSessionRequest {
|
|
cwd: string;
|
|
/** binaire à lancer — défaut "claude" ; "bash" sert aux tests d'acceptation sans quota */
|
|
command?: 'claude' | 'bash';
|
|
}
|
|
export interface SessionsListResponse {
|
|
sessions: SessionSummary[];
|
|
}
|
|
export interface SessionResponse {
|
|
session: SessionSummary;
|
|
}
|
|
|
|
// POST /sessions/:id/resume et /sessions/:id/fork (P2) : aucun corps — cwd et command
|
|
// sont TOUJOURS dérivés du :id (lu sur disque), jamais fournis par le client (cf. spike S1).
|
|
export type ResumeSessionRequest = Record<string, never>;
|
|
export type ForkSessionRequest = Record<string, never>;
|
|
|
|
// ---- Repos & worktrees (P3) ----
|
|
export interface ReposListResponse {
|
|
repos: RepoSummary[];
|
|
}
|
|
export interface RepoResponse {
|
|
repo: RepoSummary;
|
|
}
|
|
export interface CreateRepoRequest {
|
|
path: string;
|
|
label?: string;
|
|
postCreateHooks?: PostCreateHook[];
|
|
preTrust?: boolean;
|
|
}
|
|
export interface UpdateRepoRequest {
|
|
label?: string;
|
|
postCreateHooks?: PostCreateHook[];
|
|
preTrust?: boolean;
|
|
}
|
|
|
|
export interface WorktreesListResponse {
|
|
worktrees: WorktreeSummary[];
|
|
}
|
|
export interface WorktreeResponse {
|
|
worktree: WorktreeSummary;
|
|
}
|
|
export interface HookRunResult {
|
|
hookId: string;
|
|
label: string;
|
|
exitCode: number | null;
|
|
output: string;
|
|
durationMs: number;
|
|
}
|
|
export interface CreateWorktreeRequest {
|
|
branch: string;
|
|
/** true : créer la branche (`-b`) ; false : checkout d'une branche existante. */
|
|
newBranch: boolean;
|
|
/** point de départ de la nouvelle branche (défaut : HEAD courant du repo). */
|
|
baseRef?: string;
|
|
/** chemin cible du worktree (défaut : `<parent>/<repo>-wt-<branch>`). */
|
|
path?: string;
|
|
runHooks?: boolean;
|
|
preTrust?: boolean;
|
|
/** lancer une session dans le worktree créé (défaut : aucune). */
|
|
startSession?: 'claude' | 'bash' | null;
|
|
}
|
|
export interface CreateWorktreeResponse {
|
|
worktree: WorktreeSummary;
|
|
hookResults: HookRunResult[];
|
|
session: SessionSummary | null;
|
|
}
|
|
export interface AdoptWorktreeRequest {
|
|
path: string;
|
|
runHooks?: boolean;
|
|
preTrust?: boolean;
|
|
}
|
|
|
|
// ---- Groupes de travail (P5) ----
|
|
export interface GroupsListResponse {
|
|
groups: GroupSummary[];
|
|
}
|
|
export interface GroupResponse {
|
|
group: GroupSummary;
|
|
}
|
|
export interface CreateGroupRequest {
|
|
label: string;
|
|
description?: string;
|
|
color?: string;
|
|
/** ids de repos initiaux (défaut : []). */
|
|
repoIds?: string[];
|
|
}
|
|
export interface UpdateGroupRequest {
|
|
label?: string;
|
|
/** null pour effacer. */
|
|
description?: string | null;
|
|
color?: string | null;
|
|
}
|
|
export interface AddRepoRequest {
|
|
repoId: string;
|
|
}
|
|
|
|
// ---- Navigateur de répertoires (sélecteur de dossier côté web) ----
|
|
export interface FsEntry {
|
|
name: string;
|
|
/** chemin absolu du dossier */
|
|
path: string;
|
|
/** présent (true) uniquement en mode markRepos quand le dossier est un dépôt git */
|
|
isRepo?: boolean;
|
|
}
|
|
export interface FsListResponse {
|
|
/** chemin absolu listé (normalisé) */
|
|
path: string;
|
|
/** parent (null à la racine `/`) — pour le bouton « remonter » */
|
|
parent: string | null;
|
|
/** home de l'utilisateur côté serveur — point de départ par défaut */
|
|
home: string;
|
|
/** sous-dossiers uniquement, triés sans tenir compte de la casse */
|
|
entries: FsEntry[];
|
|
}
|
|
|
|
// ---- Web Push (P4) ----
|
|
export interface VapidKeyResponse {
|
|
/** clé publique VAPID (applicationServerKey côté navigateur). */
|
|
key: string;
|
|
}
|
|
export interface PushSubscribeRequest {
|
|
endpoint: string;
|
|
keys: { p256dh: string; auth: string };
|
|
}
|
|
export interface PushUnsubscribeRequest {
|
|
endpoint: string;
|
|
}
|