Files
arboretum/packages/shared/src/api.ts
Johan LEROY 416e5577cb
All checks were successful
CI / Build & test (Node 22) (push) Successful in 9m45s
CI / Build & test (Node 24) (push) Successful in 9m42s
CI / Pack & boot smoke (Node 22) (push) Successful in 9m44s
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

125 lines
3.4 KiB
TypeScript

// Types REST partagés (préfixe /api/v1).
import type { 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;
}
// ---- 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;
}