- Shell 69%
- Dockerfile 16.1%
- Just 14.9%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .forgejo/workflows | ||
| AGENTS.md | ||
| Containerfile | ||
| Justfile | ||
| pinata | ||
| README.md | ||
| renovate.json5 | ||
Frappez-la pour que le code en tombe 🎉
pinata
Lance le CLI pi.dev dans un conteneur podman, avec le dossier courant monté comme espace de travail. pi n'a accès qu'à ce dossier, et aux éventuels dossiers que vous ajoutez explicitement, pas au reste de votre machine.
Équivalent de cloche pour pi.dev. Le nom vient de la piñata.
Image publique
Une image à jour est publiée automatiquement sur git.coopix.eu/public/pinata:latest à chaque merge dans main (voir « CI/CD »). Par défaut, pinata la télécharge depuis ce registre plutôt que de construire l'image localement.
Prérequis
- podman 4.3 ou plus récent, en mode rootless (utilisateur normal, pas root)
- bash
- just, facultatif, pour l'installation en une commande
Installation
git clone <url-du-dépôt> ~/pinata
cd ~/pinata
just deploy
just deploy vérifie le script, crée le lien symbolique ~/.local/bin/pinata et récupère l'image (publiée, ou construite si le registre est indisponible). Vérifiez que ~/.local/bin est dans votre PATH ; just vous prévient si ce n'est pas le cas.
Sans just, le lien symbolique suffit, l'image étant alors téléchargée (ou construite si le registre est indisponible) au premier lancement :
ln -s ~/pinata/pinata ~/.local/bin/pinata
Dans les deux cas, le script retrouve le Containerfile à côté de son emplacement réel : ne déplacez pas le dépôt après l'installation, ou relancez just install.
Utilisation
cd ~/mon-projet
pinata
Au premier lancement, si l'image n'est pas déjà présente en local, pinata essaie d'abord de télécharger l'image publiée (git.coopix.eu/public/pinata:latest) ; si le registre est indisponible, l'image est construite localement (quelques minutes). Dans pi, tapez /login pour connecter un abonnement ou une clé d'API d'un fournisseur (Anthropic, OpenAI, etc.), ou définissez une clé d'API sur l'hôte avant de lancer pinata (voir « Variables d'environnement »). La connexion est conservée pour les lancements suivants.
Tout ce qui suit les options de pinata est transmis à pi :
pinata -p "résume ce dépôt"
Options
| Option | Effet |
|---|---|
--rebuild |
reconstruit l'image (met à jour le CLI pi) avant de lancer |
--update |
télécharge la dernière image publiée avant de lancer |
--build-only |
image seulement : la construit si besoin (de zéro avec --rebuild, la télécharge avec --update) puis quitte |
--shell |
ouvre un shell bash dans le conteneur au lieu de pi |
--include CHEMIN |
monte un dossier de plus sur /work/<nom> (lecture/écriture) ; répétable |
--include-ro CHEMIN |
idem, en lecture seule ; répétable |
--pinata-help |
affiche l'aide |
Ces options doivent être placées avant les arguments destinés à pi.
Travailler sur plusieurs projets
Pour donner à pi accès à d'autres dossiers que le projet courant, ajoutez-les avec --include (ou --include-ro si pi doit seulement les lire) :
cd ~/mon-projet
pinata --include ../ma-lib --include-ro ~/docs-api
Chaque dossier est monté à côté du projet, sur /work/<nom-du-dossier> (ici /work/ma-lib et /work/docs-api). Le projet courant reste le dossier de travail du conteneur et de pi. pi n'a pas d'option pour déclarer des dossiers supplémentaires : indiquez-lui ces chemins dans votre demande (par exemple « compare avec /work/ma-lib »).
Deux dossiers de même nom sont refusés, tout comme les chemins contenant « : ».
Variables d'environnement
| Variable | Rôle |
|---|---|
PINATA_IMAGE |
nom de l'image (défaut : localhost/pinata:latest) |
PINATA_PUBLIC_IMAGE |
image publiée téléchargée par --update, et à défaut à la place d'une construction locale (défaut : git.coopix.eu/public/pinata:latest) |
PINATA_CONFIG_DIR |
dossier hôte de la config pi (défaut : ~/.local/share/pinata) |
PINATA_PROXY |
proxy HTTP(S) sortant, tel que vu depuis le conteneur |
Les clés d'API suivantes sont transmises au conteneur si elles sont définies sur l'hôte : ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, MISTRAL_API_KEY, OPENROUTER_API_KEY, DEEPSEEK_API_KEY, GROQ_API_KEY, XAI_API_KEY. Pour les autres fournisseurs, utilisez /login dans pi.
Sont aussi transmises : TERM, COLORTERM, NO_PROXY, no_proxy et les variables de proxy (voir ci-dessous).
Ce qui est monté dans le conteneur
| Sur l'hôte | Dans le conteneur | Accès |
|---|---|---|
| dossier courant | /work/<nom-du-dossier> |
lecture/écriture |
dossiers --include / --include-ro |
/work/<nom-du-dossier> |
selon l'option |
PINATA_CONFIG_DIR |
/home/pi/.pi/agent |
lecture/écriture |
~/.gitconfig, s'il existe |
/home/pi/.gitconfig |
lecture seule |
PINATA_CONFIG_DIR contient la configuration de pi : connexion (auth.json), réglages, extensions et historique des sessions. La configuration ~/.pi/agent de l'hôte n'est pas utilisée.
Proxy
Les variables HTTP_PROXY, HTTPS_PROXY (et leurs versions en minuscules) de l'hôte sont transmises à la construction de l'image et au conteneur. Si le proxy écoute sur la machine locale (localhost, 127.0.0.1), il est injoignable depuis le conteneur : définissez alors PINATA_PROXY avec l'adresse du proxy telle que vue depuis le conteneur ; le proxy doit alors écouter sur une interface joignable depuis celui-ci. PINATA_PROXY remplace alors ces variables, à la construction (étapes apk et npm) comme au lancement ; podman garde le proxy de l'hôte pour télécharger l'image de base et l'image publiée.
Migrer depuis pi.dev installé sur l'hôte
Quand vous utilisez pi.dev directement sur votre machine, sa configuration (clés API, réglages, sessions, extensions, MCP, modèles, keybindings…) vit dans ~/.pi/agent. Pinata n'utilise pas ce dossier : il monte un autre répertoire hôte (PINATA_CONFIG_DIR, défaut ~/.local/share/pinata) sur /home/pi/.pi/agent dans le conteneur.
Pour conserver votre configuration pi.dev existante, copiez-la vers le dossier de config de pinata :
mkdir -p ~/.local/share/pinata
cp -r ~/.pi/agent/* ~/.local/share/pinata/
Vous pouvez aussi choisir un autre emplacement et le définir avec PINATA_CONFIG_DIR :
export PINATA_CONFIG_DIR=~/.pi/agent
Attention : si vous pointez
PINATA_CONFIG_DIRvers~/.pi/agent, les fichiers de ce dossier seront accessibles en lecture/écriture depuis le conteneur. Les clés API stockées dansauth.jsonseront lisibles par tout ce qui s'exécute à l'intérieur. Si ce n'est pas ce que vous souhaitez, utilisez un dossier séparé.
Ce qui est migré
Le dossier ~/.pi/agent contient :
| Fichier / dossier | Contenu |
|---|---|
settings.json |
Réglages utilisateur (préférences, outils par défaut…) |
auth.json |
Clés API et identifiants OAuth |
mcp.json |
Serveurs MCP |
models.json |
Points de terminaison et modèles |
keybindings.json |
Raccourcis clavier personnalisés |
extensions/ |
Extensions utilisateur |
skills/ |
Skills et fichiers associés |
prompts/ |
Templates de prompts (slash commands) |
themes/ |
Thèmes UI |
AGENTS.md, SYSTEM.md, APPEND_SYSTEM.md |
Instructions utilisateur globales |
sessions/ |
Historique des sessions |
Les sessions sont sauvegardées par dossier de travail. Si vous lancez pinata dans les mêmes répertoires que sur l'hôte, les sessions seront retrouvées automatiquement.
Mise à jour
Pour mettre à jour l'image avec la dernière version publiée (nouveau CLI pi, nouvelle image de base) : pinata --update ou just update.
Pour reconstruire l'image localement de zéro (met à jour le CLI pi) : pinata --rebuild ou just rebuild. La commande pi update ne peut pas mettre pi à jour dans le conteneur ; elle indique de passer par pinata --rebuild.
Pour mettre à jour pinata lui-même, faites git pull dans le dépôt.
Recettes just
| Recette | Effet |
|---|---|
just |
liste les recettes |
just deploy |
vérifie le script, crée le lien symbolique et récupère l'image (publiée, ou construite si besoin) |
just install |
crée le lien symbolique ~/.local/bin/pinata (dossier modifiable avec PINATA_BINDIR) |
just build |
récupère l'image si elle n'existe pas encore (publiée, ou construite si besoin) |
just rebuild |
reconstruit l'image de zéro (met à jour le CLI pi) |
just update |
télécharge la dernière image publiée sur le registre |
just check |
vérifie la syntaxe du script |
just uninstall |
supprime le lien symbolique et l'image ; la configuration de pi est conservée |
Limites connues
pinatarefuse de se lancer depuis votre dossier personnel ou depuis/, pour ne pas les exposer en entier.- Les clés d'API transmises et le contenu de
PINATA_CONFIG_DIRsont lisibles par tout ce qui tourne dans le conteneur, y compris les commandes lancées par pi. - Le conteneur a accès au réseau sans restriction.
- Les outils disponibles pour pi sont ceux de l'image (Node.js, git, ripgrep, jq, curl…) ; ce qu'il installe en cours de session disparaît à la fin (
--rm), sauf dans le dossier monté.
CI/CD
La construction et la publication de l'image sont automatisées via Forgejo Actions :
- Sur pull request (celles de Renovate comprises) : construction de l'image et vérification que pi répond (
pi --version), sans envoi au registre - Au merge dans main : construction et publication sur le registre public de Forgejo
git.coopix.eu/public/pinata:latest(et:shadu commit)
Avant chaque construction, la CI vérifie avec cosign la signature Sigstore des images de base Chainguard épinglées par digest dans le Containerfile ; une image hors cgr.dev/chainguard ou non épinglée par digest est refusée.
Token CI (CI_TOKEN)
Les workflows (.forgejo/workflows/) utilisent le secret CI_TOKEN du dépôt : un personal access token (PAT) du compte dédié ci-pinata sur git.coopix.eu, à renseigner dans Settings → Actions → Secrets du dépôt public/pinata.
Création du token
- Se connecter à
git.coopix.euavec le compteci-pinata, puis Settings → Applications → Generate New Token. - Choisir l'accès « All (public, private, and limited) » ou « Public only » — jamais « Specific repositories » : Forgejo n'y autorise que
read:repository,write:repository,read:issueetwrite:issue, ce qui rendread:useretread:organizationimpossibles. - Cocher les scopes du tableau ci-dessous (dans l'interface Forgejo, choisir le droit read ou write pour chaque groupe de scopes).
- Copier le token affiché une seule fois, puis mettre à jour le secret
CI_TOKENdu dépôt.
Scopes requis
Sur Forgejo, le droit write inclut read : un scope en write donne aussi la lecture.
| Scope | Droit | Utilisé par | Pourquoi |
|---|---|---|---|
user |
read | Renovate | GET /api/v1/user à l'initialisation ; sans ce scope, Renovate échoue avec « Authentication failure » |
repository |
write | CI + Renovate | lecture du dépôt et création des pull requests de mise à jour (write inclut read) |
issue |
write | Renovate | issues, labels et commentaires (exigé depuis Forgejo >= 1.20 ; write inclut read) |
organization |
read | Renovate | lecture de l'organisation public et de ses labels (exigé depuis Forgejo >= 1.20) |
package |
write | CI | connexion au registre et envoi de l'image (docker login / docker push) |
Références : scopes des tokens Forgejo et Renovate sur Forgejo.
Vérifier le token
curl -H "Authorization: token $CI_TOKEN" https://git.coopix.eu/api/v1/user
curl -H "Authorization: token $CI_TOKEN" https://git.coopix.eu/api/v1/orgs/public
La première commande doit renvoyer le compte ci-pinata, la seconde l'organisation public.
Dépannage
- Renovate échoue avec « Authentication failure » : le token manque un scope (souvent
useren read,issueen write ouorganizationen read) ou le secretCI_TOKENest vide ; passerLOG_LEVEL: debugdans.forgejo/workflows/renovate.ymldonne le détail, puis relancer le workflowrenovate(workflow_dispatch). - La CI échoue au
docker login: le scopepackageen write manque ou a expiré.
Dépôt et CI
| Élément | Emplacement |
|---|---|
| Code source | git.coopix.eu/public/pinata |
| Image publique | git.coopix.eu/public/pinata:latest |
| Workflows CI | .forgejo/workflows/ |
| Configuration Renovate | renovate.json5 |
Gestion des dépendances
Les dépendances du Containerfile (digest de l'image de base Chainguard, version épinglée du paquet npm pi) sont suivies automatiquement par Renovate : le tag de l'image via le gestionnaire dockerfile, et la version de pi épinglée dans le npm install via un gestionnaire regex (datasource npm). Les pull requests de mise à jour sont créées automatiquement selon la configuration dans renovate.json5 ; la CI construit et teste l'image de chaque pull request avant fusion.