---L’en-tête YAML : c’est tout ce que l’agent lit au démarrage.
name: spaces-adalanLe nom du dossier, en minuscules, chiffres et tirets. C’est aussi celui de l’appel explicite.
description: "Publier sur Spaces, la plateforme d'adalan (spaces.adalan.ai), une présentation HTML, un site statique ou une application (POC Node, Python, agent IA, avec base PostgreSQL), puis gérer ses sites en ligne (lister, mettre à jour, protéger par mot de passe ou en accès interne, réafficher le mot de passe, prolonger ou rendre permanent, inviter par e-mail, variables, journal, supprimer), par le connecteur adalan ou, depuis Claude Code, par SSH. À utiliser dès qu'un(e) collaborateur(trice) adalan demande de mettre en ligne, publier, déployer ou partager par un lien un livrable web, ou parle de son Space ou de ses sites sur spaces.adalan.ai."Ce que fait le skill et quand s’en servir : c’est elle qui le déclenche.
compatibility: "Demande l'accès à spaces.adalan.ai : le connecteur adalan (MCP, https://spaces.adalan.ai/mcp) dans claude.ai, Claude Desktop et l'application mobile, ou, depuis Claude Code, SSH avec une clé enregistrée sur la plateforme, bash et tar. Réservé aux collaborateurs et freelances adalan qui ont un Space."Ce qu’il faut à l’environnement : outil, logiciels, accès réseau.
metadata: author: adalan version: "1.0"évolution.correction : on compare ce numéro à celui de sa copie.
---Spaces : publier sur spaces.adalan.ai
Chaque collaborateur(trice) a un Space https://spaces.adalan.ai/<slug>/ : le slug est le segment de son adresse, par défaut son prénom et son nom (jean-durand) ; le nom du Space est celui de la personne (« Jean Durand »). Chaque site y reçoit sa propre adresse, https://spaces.adalan.ai/<slug>/<projet>/, en HTTPS, exclue des moteurs de recherche (noindex) et en ligne 90 jours, prolongeables.
Tous les sites partagent l'adresse spaces.adalan.ai : chacun est servi sous son chemin /<slug>/<projet>/, pas à la racine. Ses liens doivent donc être relatifs (voir les vérifications ci-dessous).
La documentation en ligne, à indiquer à la personne quand elle cherche à comprendre ou à s'installer : https://spaces.adalan.ai/docs/ (onboarding, connecteur claude.ai, Claude Code, publication, gestion des sites, dépannage).
Par où passer
- claude.ai, Claude Desktop, application mobile : le connecteur adalan (outils
deploy_site,list_sites,info…, adressehttps://spaces.adalan.ai/mcp). S'il manque, expliquer à la personne comment l'ajouter puis le relier à son Space : https://spaces.adalan.ai/docs/claude-ai. - Claude Code : SSH, avec la clé du poste et l'alias
adalan. L'archive part du disque sans passer par la conversation : c'est le chemin des projets construits, des applications et des gros sites. Sans clé SSH, le connecteur, s'il est ajouté à Claude Code. Voir « Depuis Claude Code, par SSH », à la fin.
Les deux mènent au même Space, avec les mêmes contrôles, le même quota et le même journal : un site publié par l'un se met à jour par l'autre. La suite nomme les outils du connecteur, avec l'équivalent SSH quand il diffère.
Publier ou mettre à jour un site
- Nom du site. Le convenir avec la personne : 3 à 40 caractères, minuscules, chiffres et tirets.
www,admin,api,mailetportailsont réservés. Le nom figure dans l'adresse transmise aux visiteurs : jamais de nom de client pour un contenu confidentiel. Publier sous un nom existant remplace le site. Pour une adresse introuvable sans son lien, ou si la personne demande un nom tiré au hasard :random_name(SSH :--tokenà la place du nom) ; le serveur tire un nom commek7mqd-2xpt9-wfb3h-nc8ra-4mxpqet le renvoie dansproject, à reprendre pour toute mise à jour. - Fichiers à publier.
index.htmlà la racine : une adresse qui ne nomme pas de fichier ouvre l'index.htmldu dossier (…/<projet>/annexes/ouvreannexes/index.html), et un dossier sansindex.htmlrépond 404. Un site statique n'exécute pas de PHP : unindex.phpn'y sert pas de page d'accueil et son code partirait en clair ; pour du PHP, publier une application. Pour un projet à construire, lancer la construction et prendre le dossier de sortie (dist/,build/,out/,_site/…). Pour une présentation en un seul fichier, la nommerindex.html(par SSH, dans un dossier dédié). - Vérifications avant envoi. Elles sont obligatoires :
- aucun secret : fichier
.env, clé, jeton d'API écrit dans le JavaScript ; le serveur refuse les fichiers sensibles connus, mais pas un jeton caché dans le code ; - aucune donnée personnelle réelle ni donnée client confidentielle sans accord écrit (charte d'usage) ; en cas de doute, demander ;
- liens et ressources relatifs, présents dans le site (pas de
file://, pas deC:\) :css/style.css,img/logo.png,page.html, jamais/css/style.css, qui mènerait à la racine despaces.adalan.ai, hors du site. Seules les ressources de la charte s'écrivent en absolu (/_adalan/…, ci-dessous). Pour un projet construit, régler le chemin de base de l'outil :base: './'(Vite),basePath: '/<slug>/<projet>'(Next.js en export statique),baseurl(Jekyll, Hugo). Le serveur signale les liens absolus qu'il trouve dans les pages et les feuilles de style (warning) ; - habillage aux couleurs d'adalan si c'est demandé : skill
charte-graphique-adalan, ou ce que sert la plateforme, à lier tel quel : la feuille de style/_adalan/adalan.css(couleurs encre et pêche, typographies, composants.btn,.card,.kicker…) et les logos/_adalan/logos/logo.svget/_adalan/logos/logo-label.svg.
- aucun secret : fichier
- Accès. Public par défaut. Proposition commerciale, document client : proposer
access="password"(SSH :--protect), qui met le site en ligne déjà protégé par mot de passe. Outil interne à adalan : proposeraccess="interne"(SSH :--interne), qui réserve le site aux collaborateurs (connexion avec leur compte Microsoft 365) et aux freelances inscrits dans Grace (code reçu par e-mail), sans mot de passe partagé.ssoen est l'ancien nom, toujours accepté. - Envoi.
deploy_siteavec tous les fichiers (files: chemin relatif et contenu,encoding: "base64"pour les images, polices et PDF),projectourandom_name, etaccess. 16 Mo et 1 000 fichiers au plus par appel : au-delà, publier en plusieurs fois (un premier envoi, puis des envois avecmerge=true), ou passer par SSH. L'outil attend que le site réponde (quelques secondes), puis renvoieproject,url,access,expires_at,online,warnings'il y a lieu et, si le site vient d'être protégé par mot de passe,password. - Contrôle.
onlinedoit valoirtrue; sinon, réessayer une minute plus tard (list_sites, oucurl -sI <url>depuis un terminal : 200 attendu pour un site public, 302 vers la page de connexion pour un site protégé ou interne). Siwarningsignale des liens absolus, les corriger et republier ; des fichiers PHP, les retirer ou publier une application. - Retouche d'un site en ligne. Pour changer quelques fichiers sans renvoyer tout le site :
read_site_filessans chemin liste les fichiers en ligne, avec des chemins il en renvoie le texte. Ensuite,deploy_siteavecmerge=trueet les seuls fichiers modifiés ;removeretire des fichiers ou des dossiers. - Compte rendu à la personne. Donner l'adresse et la date d'expiration. Si le site est protégé, donner le mot de passe, que le visiteur saisit sur une page adalan : à transmettre au visiteur par un autre canal que l'adresse si possible ;
site_passwordle réaffiche. Pour l'envoyer à des destinataires que la personne nomme :invite_to_site(voir « Gérer les sites »). Un site interne n'a rien à transmettre : les collaborateurs se connectent avec Microsoft, les freelances demandent un code par e-mail sur la page de connexion.
Publier une application
Pour un POC dynamique (Node, Python, PHP, agent IA avec clé d'API) : même envoi, avec kind="docker" (SSH : --type docker).
- Conditions. Un
Dockerfileà la racine. L'application écoute sur0.0.0.0, au port donné par la variablePORT(8080). Elle a droit à 512 Mo de mémoire et un demi-processeur. Chaque Space compte au plus 3 applications. - Chemin. L'application est servie sous
https://spaces.adalan.ai/<slug>/<projet>/. Caddy retire ce préfixe : elle reçoit/,/api/items… comme si elle était à la racine. Le préfixe arrive dans la variableBASE_PATH(/<slug>/<projet>) et l'en-têteX-Forwarded-Prefix. Dans ses pages et son JavaScript, les liens sont relatifs (api/items,static/app.css) ou préfixés parBASE_PATH, jamais/api/items. Les redirections vers/…et les cookies posés pour/sont ramenés sous son chemin par le serveur. Selon le cadriciel : FastAPIFastAPI(root_path=os.environ.get("BASE_PATH", "")), FlaskProxyFix(app.wsgi_app, x_prefix=1)puisurl_for, Express : liens relatifs dans les gabarits. - Secrets. Jamais de clé d'API dans le code ni dans l'image : le serveur refuse les fichiers
.env. Les définir avecset_app_env(values, etunsetpour en retirer), qui relance l'application ; sans l'un ni l'autre, il liste les variables, jamais leurs valeurs. Par SSH, toujours par l'entrée standard (voir la fin). - Envoi. La construction peut prendre quelques minutes au premier envoi. La plateforme construit l'image, lance le conteneur et vérifie qu'il répond. Si la nouvelle version échoue, la précédente est remise en service et le journal montre l'erreur.
- Base de données.
create_database(SSH :db create <projet>) crée une base PostgreSQL dédiée. Elle ajouteDATABASE_URLet les variablesPG*à l'application, qui redémarre. L'application doit créer ses tables elle-même. - Diagnostic.
app_logs(SSH :logs <projet> --lines 100).
Une application en accès interne reçoit l'adresse du visiteur dans l'en-tête X-Adalan-Email, son nom dans X-Adalan-Name (encodé en URL) et sa connexion dans X-Adalan-Auth (microsoft pour un collaborateur, email pour un freelance) : elle peut s'en servir pour personnaliser l'accueil, tracer les actions ou réserver une page aux collaborateurs, sans gérer de mots de passe.
Si l'application a besoin d'une clé pour démarrer, le premier envoi peut échouer faute de clé : définir alors la clé, ce qui relance l'application.
Gérer les sites
| Besoin | Connecteur | SSH : ssh adalan adalan … |
|---|---|---|
| Le Space, ses adresses, le disque utilisé | info |
info |
| Voir ses sites | list_sites |
list (ou --json) |
| Protéger par mot de passe (nouveau mot de passe généré) | protect_site |
protect <projet> |
| Protéger par un mot de passe choisi (8 à 128 caractères) | protect_site avec password |
protect <projet> --password-stdin (voir la fin) |
| Réafficher le mot de passe d'un site | site_password |
password <projet> |
| Réserver à l'accès interne | protect_site avec access="interne" |
protect <projet> --interne |
| Retirer la protection | protect_site avec access="public" |
protect <projet> --off |
| Prolonger (durée comptée à partir d'aujourd'hui, 1 à 365 jours) | extend_site avec days |
extend <projet> --days 90 |
| Fixer le dernier jour d'accès (un an au plus) | extend_site avec until |
extend <projet> --until 2026-12-31 |
| Rendre permanent (plus de date de fin) | extend_site avec permanent |
extend <projet> --permanent |
| Envoyer le lien (et le mot de passe) par e-mail | invite_to_site ; include_password=false pour ne pas joindre le mot de passe |
invite <projet> --to client@exemple.fr ; --no-password, message par --message-stdin |
| Fichiers en ligne, ou contenu d'un fichier | read_site_files |
files <projet> [chemin…] |
| Supprimer (hors ligne tout de suite, fichiers, conteneur et base effacés) | delete_site |
delete <projet> |
| Journal d'une application | app_logs |
logs <projet> |
| Variables d'une application | set_app_env |
env <projet> (voir la fin pour les définir) |
| Base PostgreSQL d'une application | create_database |
db create <projet> |
Dans le navigateur, la page du Space, https://spaces.adalan.ai/<slug>/ (adresse donnée par info), liste ses sites. Celle d'un Space collaborateur s'ouvre avec le compte Microsoft, un code par e-mail ou le code d'accès du connecteur ; son bouton « Gérer le site » donne les informations, les fichiers, l'accès, le mot de passe, la durée, l'invitation et la suppression. Celle d'un Space éphémère ou public, géré par l'administrateur, est ouverte à qui a son lien.
Demander confirmation avant de supprimer : la suppression est définitive. N'envoyer d'invitation qu'aux adresses que la personne a données pour ce site, après lui avoir dit ce qui partira (lien, date de fin, mot de passe) ; 10 destinataires par envoi, 50 par Space sur 24 heures.
Erreurs fréquentes
| Message | Que faire |
|---|---|
fichiers sensibles refusés : … |
Retirer ces fichiers et republier. Par SSH seulement, --force si la personne confirme que ce ne sont pas des secrets ; le connecteur ne force jamais. |
pas d'index.html à la racine |
Le site répondra 404 : ajouter ou renommer la page d'accueil en index.html. |
liens absolus vers la racine (/…), ou site en ligne sans styles ni images |
Rendre relatifs les liens des fichiers cités (css/style.css au lieu de /css/style.css), ou régler le chemin de base de l'outil de construction, puis republier. |
fichiers PHP dans … |
Le site statique sert ces fichiers en clair, code source compris : les retirer et republier, ou publier une application (Dockerfile qui exécute le PHP). |
16 Mo au plus par envoi, 1000 fichiers au plus par envoi |
Publier en plusieurs fois : un premier envoi, puis des envois avec merge=true ; ou passer par SSH. |
limite de 20 sites atteinte |
Lister les sites et en supprimer un, avec l'accord de la personne. |
quota du Space atteint |
5 Go par Space : supprimer des sites, ou alléger (images, vidéos). |
Dockerfile absent à la racine |
Ajouter un Dockerfile, ou publier en site statique. |
construction de l'image en échec |
Lire les dernières lignes affichées (dépendance introuvable, commande en erreur), corriger, republier. |
la nouvelle version ne répond pas |
L'application doit écouter sur 0.0.0.0 et le port PORT ; lire le journal affiché. La version précédente reste en ligne. |
| Application en ligne, mais pages sans styles, appels d'API en 404 | Liens absolus dans ses pages ou son JavaScript : les rendre relatifs ou les préfixer par BASE_PATH. |
limite de 3 applications atteinte |
Supprimer une application, avec l'accord de la personne. |
le mot de passe … a été posé avant que la plateforme garde les mots de passe |
Il ne peut pas être réaffiché : en poser un nouveau (protect_site), avec l'accord de la personne, puis le lui donner. |
les courriels ne sont pas encore configurés sur la plateforme |
Les invitations attendent l'administrateur : donner le lien et le mot de passe à la personne, qui les transmet elle-même. |
Connecteur refusé, ou SSH en Permission denied (publickey), alors que l'accès fonctionnait |
L'administrateur a peut-être désactivé le Space, ou coupé l'accès de Claude : la personne s'adresse à lui. |
Durée de vie et limites
- Un site ou une application vit 90 jours. La personne reçoit un rappel 7 jours avant l'échéance. À l'échéance, le site est mis hors ligne (page « contenu expiré »), puis supprimé 30 jours plus tard. Une prolongation le remet en ligne à tout moment avant la suppression. Un site rendu permanent n'expire pas : à réserver à ce qui doit durer, la charte d'usage demandant de ne pas laisser traîner les livrables.
- Par envoi : 16 Mo et 1 000 fichiers par le connecteur, 2 Go et 20 000 fichiers par SSH. Par Space : 5 Go et 20 sites, dont 3 applications.
- Pas de nom de domaine personnalisé.
- Une adresse de projet mal tapée donne la page 404 adalan.
- Tous les sites partagent l'adresse
spaces.adalan.ai: le stockage du navigateur (localStorage) est commun à tous les sites de la plateforme. Un site ou une application n'y range rien de confidentiel.
Depuis Claude Code, par SSH
Claude Code passe par SSH, avec la clé du poste, vers spaces.adalan.ai. Le serveur n'accepte que les commandes adalan : pas de shell, pas de scp, pas de rsync. Les fichiers partent en archive tar dans le flux SSH, depuis bash, ou Git Bash sous Windows : PowerShell 5 corrompt les flux binaires.
Accès (à vérifier une fois par poste)
ssh adalan adalan info-
Réponse avec le Space et le quota : tout est prêt.
-
Could not resolve hostname adalan: l'alias manque. Demander le slug du Space de la personne, celui de son adresse (jean-durandpourspaces.adalan.ai/jean-durand/, en général son prénom et son nom), puis ajouter dans~/.ssh/config(avec son accord) :Host adalan HostName spaces.adalan.ai User jean-durandAjouter
IdentityFile ~/.ssh/<clé>si la clé enregistrée n'est pas la clé par défaut du poste. -
Permission denied (publickey): la clé du poste n'est pas enregistrée. La personne envoie sa clé publique (cat ~/.ssh/id_ed25519.pub, oussh-keygen -t ed25519pour en créer une) à l'administrateur de la plateforme. Ne jamais transmettre la clé privée. Si l'accès fonctionnait jusque-là, le Space a peut-être été désactivé par l'administrateur : le lui demander.
Publier
COPYFILE_DISABLE=1 tar -czf - -C <dossier> . | ssh adalan adalan deploy <projet> --jsonAjouter --protect ou --interne pour l'accès, --type docker pour une application (construction : quelques minutes). --token à la place du nom tire un nom au hasard (pas avec --merge). La commande attend que le site réponde, puis renvoie les mêmes champs que deploy_site.
Retouche : ssh adalan adalan files <projet> liste les fichiers en ligne, ssh adalan adalan files <projet> index.html en affiche un. N'envoyer ensuite que les fichiers modifiés, avec --merge ; --remove <chemin> retire un fichier :
COPYFILE_DISABLE=1 tar -czf - -C <dossier-des-fichiers-modifiés> . | ssh adalan adalan deploy <projet> --merge --jsonSecrets et mots de passe
Toujours par l'entrée standard, pour qu'ils n'apparaissent dans aucune ligne de commande :
printf 'OPENAI_API_KEY=%s\n' "$CLE" | ssh adalan adalan env <projet> --stdin
printf '%s\n' '<mot de passe>' | ssh adalan adalan protect <projet> --password-stdinssh adalan adalan env <projet> liste les variables sans leurs valeurs ; --unset NOM en retire une.
Erreurs propres à SSH
| Message | Que faire |
|---|---|
l'archive contient seulement le dossier « dist » |
Refaire l'archive depuis l'intérieur du dossier : tar -czf - -C dist . |
lien non pris en charge |
Remplacer les liens symboliques par de vrais fichiers. |