forked from bots-garden/ori
| ✨ Workspace panel, selectors, previews, desktop app, sandbox template, resizable file tree, light/dark theme | 1 | # Référence : API workspace |
| 2 | ||
| 3 | > Description neutre et exhaustive des endpoints derrière le panneau workspace et les sélecteurs du composer : l'API fichiers, l'endpoint des skills et le WebSocket du terminal. Les chemins relatifs se résolvent contre le `--cwd` du serveur ; les chemins absolus sont utilisés tels quels (accès volontairement non restreint — ori vise des sandboxes déjà isolées). | |
| 4 | ||
| 5 | ## GET /api/files | |
| 6 | ||
| 7 | Liste un répertoire. | |
| 8 | ||
| 9 | | Paramètre de requête | Type | Défaut | Description | | |
| 10 | | --- | --- | --- | --- | | |
| 11 | | `path` | chaîne | la racine du workspace | Répertoire à lister. | | |
| 12 | ||
| 13 | Réponse `200` : | |
| 14 | ||
| 15 | ```json | |
| 16 | { "path": "/travail", "entries": [ { "name": "src", "path": "/travail/src", "isDir": true, "size": 0 } ] } | |
| 17 | ``` | |
| 18 | ||
| 19 | Les entrées sont triées répertoires d'abord, puis fichiers, chaque groupe par ordre alphabétique. | |
| 20 | ||
| 21 | ## GET /api/files/search | |
| 22 | ||
| 23 | Recherche des fichiers récursivement sous la racine du workspace, pour le sélecteur `@` du composer. | |
| 24 | ||
| 25 | | Paramètre de requête | Type | Défaut | Description | | |
| 26 | | --- | --- | --- | --- | | |
| 27 | | `q` | chaîne | `""` | Sous-chaîne, insensible à la casse, cherchée dans le chemin relatif à la racine. Vide renvoie les premiers fichiers. | | |
| 28 | | `limit` | entier | 50 | Nombre maximal de résultats ; plafonné à 500. | | |
| 29 | ||
| 30 | Réponse `200` : | |
| 31 | ||
| 32 | ```json | |
| 33 | { "root": "/travail", "files": [ { "name": "main.go", "path": "/travail/src/main.go", "relPath": "src/main.go" } ] } | |
| 34 | ``` | |
| 35 | ||
| 36 | `path` est absolu (utilisable dans les autres endpoints), `relPath` utilise des barres obliques. Les résultats sont classés : d'abord les fichiers dont le nom de base contient la requête, puis les chemins relatifs les plus courts, puis l'ordre alphabétique. Le parcours n'entre jamais dans `.git` ni `node_modules`, ignore les entrées illisibles et s'arrête après 50 000 entrées de répertoire. `files` est toujours un tableau (`[]` sans correspondance). Une racine absente donne un `404`. | |
| 37 | ||
| 38 | ## GET /api/file | |
| 39 | ||
| 40 | Lit un fichier texte. | |
| 41 | ||
| 42 | | Paramètre de requête | Type | Défaut | Description | | |
| 43 | | --- | --- | --- | --- | | |
| 44 | | `path` | chaîne | — | Fichier à lire. | | |
| 45 | ||
| 46 | Réponse `200` : `{ "path": "/travail/README.md", "content": "…" }` | |
| 47 | ||
| 48 | ## PUT /api/file | |
| 49 | ||
| 50 | Écrit un fichier texte, en créant les répertoires parents si besoin. | |
| 51 | ||
| 52 | | Paramètre de requête | Type | Défaut | Description | | |
| 53 | | --- | --- | --- | --- | | |
| 54 | | `path` | chaîne | — (requis) | Fichier à écrire. | | |
| 55 | ||
| 56 | Corps : `{ "content": "…" }` — réponse `200` : `{ "path": "…", "status": "saved" }` | |
| 57 | ||
| 58 | ## GET /api/raw | |
| 59 | ||
| 60 | Diffuse les octets d'un fichier tels quels — c'est ainsi que la preview affiche les images. Pas de plafond de taille, pas d'exigence de texte ; les requêtes `Range` sont honorées (`http.ServeContent`). | |
| 61 | ||
| 62 | | Paramètre de requête | Type | Défaut | Description | | |
| 63 | | --- | --- | --- | --- | | |
| 64 | | `path` | chaîne | — (requis) | Fichier à diffuser. | | |
| 65 | ||
| 66 | Réponse `200` avec les octets du fichier, `X-Content-Type-Options: nosniff`, et un `Content-Type` choisi dans cet ordre : | |
| 67 | ||
| 68 | | Extension | Content-Type | | |
| 69 | | --- | --- | | |
| 70 | | `.png` `.jpg` `.jpeg` `.gif` `.webp` `.svg` `.bmp` `.ico` `.avif` | types image figés (`image/png`, `image/jpeg`, `image/gif`, `image/webp`, `image/svg+xml`, `image/bmp`, `image/x-icon`, `image/avif`) | | |
| 71 | | toute autre extension connue | la table mime de l'hôte (p. ex. `text/markdown; charset=utf-8`) | | |
| 72 | | inconnue | détecté sur les 512 premiers octets | | |
| 73 | ||
| 74 | ## GET /api/skills | |
| 75 | ||
| 76 | Liste les skills Claude Code disponibles pour la session, pour le sélecteur `/` du composer. | |
| 77 | ||
| 78 | Réponse `200` : | |
| 79 | ||
| 80 | ```json | |
| 81 | { "skills": [ { "name": "quality", "description": "Audit code quality with qlty.", "path": "/travail/.claude/skills/quality/SKILL.md", "source": "project" } ] } | |
| 82 | ``` | |
| 83 | ||
| 84 | Un skill est un répertoire contenant un `SKILL.md`, cherché dans `<cwd>/.claude/skills/*/` (`source: "project"`) et `~/.claude/skills/*/` (`source: "user"`). `name` et `description` viennent du frontmatter YAML du fichier (`clé: valeur`, valeurs entre guillemets et scalaires bloc `>` / `|` compris) ; un nom absent est remplacé par le nom du répertoire, une description absente par `""`. Un skill projet masque un skill utilisateur du même nom. Résultats triés par nom ; `skills` est toujours un tableau. | |
| 85 | ||
| 86 | ## Erreurs de l'API fichiers | |
| 87 | ||
| 88 | Toutes les erreurs sont en JSON : `{ "error": "message" }`. | |
| 89 | ||
| 90 | | Statut | Cause | | |
| 91 | | --- | --- | | |
| 92 | | 400 | `path` manquant sur PUT ou `GET /api/raw`, corps JSON invalide, ou lecture d'un répertoire. | | |
| 93 | | 403 | Permission refusée par le système de fichiers. | | |
| 94 | | 404 | Le chemin (ou la racine du workspace, pour la recherche) n'existe pas. | | |
| 95 | | 413 | Fichier de plus de 5 Mio (`GET /api/file` seulement ; `/api/raw` n'a pas de plafond). | | |
| 96 | | 415 | Le fichier n'est pas du texte UTF-8 valide (`GET /api/file` seulement). | | |
| 97 | ||
| 98 | ## GET /ws/terminal | |
| 99 | ||
| 100 | Bascule en WebSocket et démarre un shell (depuis `$SHELL`, repli sur `bash` puis `sh`, avec `TERM=xterm-256color`) dans un pseudo-terminal, dans le `--cwd` du serveur. | |
| 101 | ||
| 102 | | Direction | Type de trame | Contenu | | |
| 103 | | --- | --- | --- | | |
| 104 | | serveur → client | binaire | Octets bruts de la sortie du terminal. | | |
| 105 | | client → serveur | texte | `{"type":"input","data":"…"}` — frappes écrites dans le pty. | | |
| 106 | | client → serveur | texte | `{"type":"resize","cols":N,"rows":N}` — changement de taille. | | |
| 107 | ||
| 108 | Le socket se ferme avec un statut de fermeture normale quand le shell se termine ; fermer le socket tue le shell. Les trames texte malformées sont ignorées. |