// 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; /** id du token de la session courante — sert à marquer « courant » dans la liste des tokens. */ tokenId: string; tokenLabel: string; serverVersion: string; } // ---- Gestion des tokens d'accès (onglet Réglages) ---- export interface TokenInfo { id: string; label: string; createdAt: string; lastUsedAt: string | null; /** true pour le token de la session courante. */ current: boolean; } export interface TokensListResponse { tokens: TokenInfo[]; } export interface CreateTokenRequest { label: string; } export interface CreateTokenResponse { id: string; label: string; /** valeur en clair — affichée une seule fois, jamais re-récupérable. */ token: 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; export type ForkSessionRequest = Record; // ---- 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; /** true = masquer le repo (exclu du dashboard, conservé en DB) ; false = ré-afficher. */ hidden?: boolean; } /** Résultat d'un scan de découverte (POST /api/v1/repos/discover). */ export interface DiscoverReposResponse { /** dossiers-repos trouvés sur disque. */ scanned: number; /** repos réellement insérés (nouveaux, non déjà enregistrés). */ added: number; durationMs: number; /** true si la limite (maxRepos / timeout) a été atteinte avant la fin du scan. */ truncated: 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 : `/-wt-`). */ 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; } // ---- Réglages & info serveur (onglet Réglages) ---- /** Config runtime non sensible du daemon — lecture seule (changée via flags CLI + redémarrage). */ export interface ServerInfo { version: string; port: number; bind: string; allowedOrigins: string[]; dataDir: string; /** clé publique VAPID (sûre à exposer) ; null si push indisponible. */ vapidPublicKey: string | null; vapidContact: string; } export interface SettingsResponse { /** réglages modifiables à chaud (allow-list serveur — jamais les secrets). */ settings: { giteaUrl: string | null; /** racines absolues scannées pour la découverte auto des repos (défaut : home). */ scanRoots: string[]; /** intervalle du re-scan périodique en minutes ; 0 = périodique désactivé. */ scanIntervalMin: number; }; server: ServerInfo; } export interface UpdateSettingsRequest { /** URL de l'instance Gitea (http/https) ; null ou '' pour effacer. */ giteaUrl?: string | null; /** racines absolues à scanner (chemins normalisés, ≤ 16) ; remplace la liste. */ scanRoots?: string[]; /** intervalle du re-scan périodique en minutes (0–1440 ; 0 désactive). */ scanIntervalMin?: number; }