Le probleme
Les CLI agentiques actuelles sont monolithiques. Claude Code, Codex CLI, Gemini CLI — chaque provider livre un binaire ferme ou le modele, les outils, la memoire, l'orchestration sont soudes. Le client prend tout ou rien.
Ce design decoule du modele couteau-suisse. Mais si le marche evolue vers des hubs specialises interoperables, la CLI doit changer de nature. Elle ne peut plus etre le produit du provider. Elle devient l'interface entre le provider et le hub.
Design : trois decisions
1. SQLite comme registre de capabilities, hot-reload
Le registre des capabilities est une base SQLite locale. Pas un fichier YAML, pas un endpoint distant — un fichier versionnable, requetable, et rechargeable a chaud sans redemarrage de session.
Le schema est minimal :
CREATE TABLE capabilities (
name TEXT PRIMARY KEY,
category TEXT NOT NULL, -- inference, tool, analysis, generation
proficiency TEXT, -- expert, advanced, basic
constraints TEXT, -- JSON: limites, interdictions
active INTEGER DEFAULT 0
);
CREATE TABLE provider_profiles (
provider TEXT NOT NULL,
model TEXT NOT NULL,
capability TEXT NOT NULL REFERENCES capabilities(name),
proficiency TEXT NOT NULL,
max_context INTEGER,
latency_p95 INTEGER, -- ms
cost_per_1k REAL,
UNIQUE(provider, model, capability)
);
Au lancement, la CLI charge le profil du provider connecte. A chaque changement de modele ou de session, le registre est recharge a chaud. Le hub peut mettre a jour le fichier SQLite pendant que la CLI tourne — le pattern hot-reload garantit la prise en compte sans interruption.
2. Negociation de session explicite
En debut de session, la CLI :
- Interroge le modele connecte pour obtenir ses capabilities declarees.
- Croise avec le registre local (le provider peut declarer
code_gen: expert, le registre local peut contraindrecode_gen: Go onlyselon le contexte hub). - Affiche a l'usager la liste des capabilities disponibles.
- L'usager active celles qu'il veut pour cette session.
Session avec claude-opus-4-6 (Anthropic)
Capabilities disponibles :
[x] code_generation expert Go, Python, TS
[x] file_io natif lecture/ecriture locale
[x] sql_query expert SQLite, Postgres
[ ] image_analysis basic via bridge
[x] shell_exec natif sandbox par defaut
[ ] web_fetch basic rate-limited
Activer/desactiver : tapez le nom. Entree pour continuer.
Pas de magie. L'usager voit ce que le modele sait faire, a quel niveau, et decide ce qu'il autorise. Les capabilities non activees ne sont pas appelables pendant la session — pas de decouverte par echec, pas de fallback silencieux.
Apres negociation, le LLM produit de l'inference dans le perimetre active, pour le hub connecte. Le hub fournit le contexte (memoire, conventions, taches). Le modele execute dans les limites de la session.
3. Autorisation externalisee par defaut
C'est la decision de design la plus importante. Les CLI actuelles gerent les autorisations en interne : "appuie sur Y pour autoriser cette action". Ce mode — human-push, action par action, dans le terminal — est un vestige du CLI prehistorique. Il ne scale pas :
- Un agent qui execute 200 actions par session ne peut pas demander confirmation 200 fois.
- Un hub medical ou juridique a des regles de compliance qui ne se reduisent pas a Y/N.
- Un workflow multi-agents ou chaque agent demande des permissions au terminal est inutilisable.
L'OpenCLI externalise l'autorisation des le premier jour :
Le modele par defaut : l'autorisation est un service externe. Le hub (ou un service d'auth dedie) recoit les demandes d'autorisation, applique les regles (compliance sectorielle, politique d'entreprise, perimetre de session), et repond. La CLI ne decide rien — elle transmet.
Flux par defaut :
LLM veut executer shell_exec("rm -rf /tmp/build")
→ CLI envoie la demande au service d'auth
→ Le service applique les regles du hub
(sandbox OK, /tmp autorise, rm autorise en build)
→ Reponse : autorise
→ CLI execute
LLM veut executer shell_exec("git push --force")
→ CLI envoie la demande au service d'auth
→ Le service applique les regles
(force push interdit sur main, alerte)
→ Reponse : refuse, raison: "force push on protected branch"
→ CLI bloque + affiche la raison
Le mode degrade : quand il n'y a pas de hub, pas de service d'auth — usage local, experimentation, debug — la CLI retombe sur le mode classique : confirmation humaine dans le terminal, action par action. C'est une option, pas le defaut. Un flag explicite :
opencli --auth=manual # mode prehistorique, Y/N dans le terminal
opencli --auth=hub # defaut, delegation au service d'auth du hub
opencli --auth=policy # regles locales dans un fichier SQLite
Le troisieme mode (policy) est un intermediaire : un fichier SQLite local contient les regles d'autorisation, sans besoin de hub distant. C'est le mode adapte aux equipes qui veulent des regles partagees sans infrastructure.
CREATE TABLE auth_rules (
capability TEXT NOT NULL,
pattern TEXT NOT NULL, -- glob ou regex sur l'argument
decision TEXT NOT NULL, -- allow, deny, ask
reason TEXT,
priority INTEGER DEFAULT 0
);
-- Exemples :
INSERT INTO auth_rules VALUES
('shell_exec', 'rm -rf /*', 'deny', 'destruction racine', 100),
('shell_exec', 'git push*main', 'ask', 'push sur main', 50),
('file_io', '/tmp/*', 'allow', 'zone temporaire', 0),
('file_io', '.env*', 'deny', 'secrets', 100);
Meme pattern SQLite, meme hot-reload. Les regles sont versionnables, partageables, auditables.
Architecture resultante
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Provider │────▶│ OpenCLI │◀────│ Hub │
│ (modele) │ │ (pont) │ │ (MP) │
└─────────────┘ └──────┬───────┘ └──────┬──────┘
│ │
┌──────▼───────┐ ┌──────▼──────┐
│ capabilities │ │ auth │
│ .sqlite │ │ (externe) │
└──────────────┘ └─────────────┘
- Le provider declare ses capabilities. Il est interchangeable.
- La CLI est un pont leger. Elle negocie, transmet, execute. Elle ne possede ni memoire, ni conventions, ni orchestration.
- Le hub possede le management plane. Il fournit contexte, taches, compliance.
- Les capabilities vivent dans un SQLite local, hot-reloadable.
- L'auth est externalisee par defaut. Le mode manuel est un fallback, pas la norme.
Ce que ca change
Pour le provider : declarer un profil de capabilities dans un format standard, pas reimplementer une CLI entiere. Reduire le cout d'entree dans l'ecosysteme hub.
Pour le hub : brancher n'importe quel modele sans integration specifique. Router les taches par competence. Appliquer la compliance une seule fois, pas par provider.
Pour l'usager : voir explicitement ce que le modele sait faire, choisir ce qu'il active, et ne plus taper Y 200 fois par session. Les regles d'autorisation sont lisibles, modifiables, partageables — pas enfouies dans un binaire.
Pour le marche : les modeles sont en concurrence sur les capabilities declarees et verifiees, pas sur la qualite de leur CLI. L'innovation passe dans l'inference et la specialisation, pas dans l'outillage.
Convergence
L'article precedent posait le hub specialise comme position de marche. L'OpenCLI est le protocole qui rend cette position viable :
- Le hub est le management plane human-driven.
- Le modele est un fournisseur d'inference interchangeable.
- La CLI est un standard ouvert — SQLite, hot-reload, auth externalisee.
- Aucun des trois ne possede les deux autres.
Le modele infere. Le hub opere. La CLI connecte. L'autorisation, ca se delegue.