bloom-terminal
v0.1.0
Published
Terminal Bloom : se connecter a l'app Bloom Experience depuis un poste de travail et y lancer des operations.
Readme
Terminal Bloom
Le programme que l'on installe sur un poste de travail pour agir sur l'app Bloom depuis un terminal. Il ne contient aucune connaissance métier : il connecte, garde la session, transmet les commandes à l'app et affiche la réponse. Le catalogue de ce qui est faisable vit dans l'app, pas ici, ce qui permet d'ajouter une capacité sans réinstaller quoi que ce soit.
À ne pas confondre avec le dossier cli/ du dépôt, qui est l'outil interne
d'administration : celui-là passe par une clé maîtresse et n'est pas
partageable. Les deux ne se mélangent jamais.
Commandes
bloom login # ouvrir une session (mot de passe demandé à l'invite)
bloom qui-suis-je # qui est connecté, et ce que cette personne peut lancer
bloom logout # fermer la session ici et côté serveurbloom qui-suis-je est le bon premier appel d'une session Claude Code : il
évite de tâtonner en lançant des commandes qui seront refusées.
Tout le reste passe par la forme bloom <domaine> <objet> <action> [options],
détaillée ci-dessous. Ce programme ne connaît lui-même aucun domaine, aucun
objet, aucune action : tout vient de l'app, interrogée à la demande. Ajouter
une capacité côté app la rend donc disponible ici sans rien réinstaller.
L'aide en escalier
Deux marches, jamais plus d'une à la fois — le catalogue complet ne s'affiche jamais en un seul geste, quelle que soit la combinaison de paramètres tentée. C'est voulu : c'est l'économie de contexte qui a fait préférer ce terminal au format MCP, et une aide qui déballerait tout l'annulerait.
bloom --help # les domaines existants, une ligne chacune
bloom commercial --help # le détail des seules opérations du domaine « commercial »Le détail d'un domaine (deuxième marche) montre, pour chaque opération : son
identifiant complet (commercial.devis.lister), une phrase de description, si
elle écrit ou lit seulement, si elle est destructive, et ses paramètres (nom,
type, obligatoire ou non). Il ne montre jamais le détail d'un second domaine en
même temps.
L'aide est gardée un court moment sur le poste (cinq minutes) pour ne pas refaire un aller-retour à chaque commande ; elle se rafraîchit d'elle-même passé ce délai, sans geste à faire, pour qu'une capacité ajoutée côté app apparaisse rapidement.
Lancer une opération
bloom commercial devis lister --entite_id bloom --statut envoye
bloom commercial devis supprimer --id <uuid> --confirmerChaque mot après bloom se traduit directement : le premier domaine, le
deuxième l'objet, le troisième l'action — commercial devis lister devient
l'opération commercial.devis.lister. Les options suivantes (--cle valeur,
--cle=valeur, ou --cle seul pour un booléen) deviennent les arguments de
l'opération, tels quels. Ce programme ne valide rien lui-même : c'est l'app qui
juge si l'opération existe et si les paramètres conviennent, avec un message
qui dit quoi corriger sinon (PARAMETRE_INVALIDE, OPERATION_INCONNUE…).
Confirmation. Une opération destructive (une suppression, par exemple) est
refusée par l'app tant que --confirmer n'est pas ajouté à la même commande.
Il n'y a pas de confirmation interactive : depuis un terminal piloté par
Claude Code, la relance explicite du même appel avec --confirmer est le
geste qui vaut accord.
Sorties. Par défaut, la réponse est mise en forme pour être lue. Ajouter
--json (n'importe où après le domaine) pour recevoir la forme brute, telle
que l'app l'a rendue — utile pour l'enchaînement plutôt que la lecture.
Listes tronquées. Une opération *.lister ne renvoie que 20 lignes par
défaut, 100 au plus. En sortie lisible, une page qui ne montre pas tout se
signale explicitement, avec le paramètre à ajouter pour voir la suite
(--offset <n>, et --limite jusqu'à 100 si besoin) — sans cela, rien ne dit
qu'il en restait, et une liste de 20 lignes sur 45 se lirait comme le compte
entier.
Erreurs. Un refus de l'app garde son code stable (DROIT_INSUFFISANT,
PARAMETRE_INVALIDE, CONFIRMATION_REQUISE…) et un message en français qui
dit quoi faire — relancer la connexion, corriger un paramètre, ou rajouter
--confirmer. Le code de sortie du programme est alors 1.
Le mot de passe n'entre que par l'invite masquée
C'est la règle centrale de ce programme, et elle est volontairement rigide. Le
mot de passe est refusé s'il est passé en paramètre (--mot-de-passe, -p,
--password…), par variable d'environnement (BLOOM_MOT_DE_PASSE et
équivalents) ou par entrée redirigée (echo … | bloom login). Sans terminal
interactif, la commande échoue en expliquant pourquoi.
La raison : ce terminal est piloté par Claude Code. Un mot de passe fourni autrement qu'à l'invite resterait écrit dans un historique de conversation, dans l'historique du shell et dans les journaux de la machine, c'est-à-dire à trois endroits où personne ne pense à aller l'effacer.
La session sur le disque
Le laissez-passer et son moyen de renouvellement sont écrits dans
~/.bloom/session.json, en 0600, dans un dossier 0700. Le mot de passe n'y
est jamais écrit : il est échangé contre un jeton à la connexion, puis oublié.
Les permissions sont revérifiées à chaque lecture : un fichier devenu lisible par d'autres comptes fait échouer la commande avec la marche à suivre, plutôt qu'un simple avertissement qui passerait inaperçu.
Le jeton d'accès vaut une heure. Quand l'app répond qu'il a expiré, le programme
le renouvelle et rejoue l'appel une seule fois, sans le dire. Il n'y a pas
de reprise en boucle : si le second essai échoue aussi, la commande s'arrête et
renvoie vers bloom login.
Configuration
Le paquet ne contient que deux valeurs, toutes deux publiques : l'adresse de
l'app et la clé publique Supabase, la même que celle déjà servie dans le site
web. Aucune clé d'administration ne doit y entrer, et le programme refuse de
démarrer s'il en reconnaît une (terminal/src/config.ts, vérifié par
terminal/paquet.test.ts).
Ces valeurs sont figées dans src/config.ts au moment de publier le paquet
(BLO-608). En attendant, et pour viser un déploiement d'essai, elles se
surchargent par l'environnement :
| Variable | Rôle |
|---|---|
| BLOOM_APP_URL | Adresse de l'app à interroger |
| BLOOM_SUPABASE_URL | Adresse du serveur d'authentification |
| BLOOM_SUPABASE_ANON_KEY | Clé publique Supabase |
Développement
bun run test # depuis la racine du dépôt : les tests de ce dossier y sont inclus
cd terminal && npx tsc -p tsconfig.json # fabrique dist/, ce qui part sur npmLe paquet doit rester installable seul : aucun fichier de terminal/ n'importe
quoi que ce soit du reste du dépôt, et paquet.test.ts échoue si cela arrive.
Seul dist/ est publié (files dans package.json), donc ni les tests ni le
faux terminal qui les sert.
