---
tags: [note, Automatisation]
type: "note"
nature: documentation # Options : portrait, lieu, info, concept, script, process, tuto, none
ressource: true
univers: PERSO
projects:
  - "[[03_PROJETS/VPS-IA]]"
date: "[[01_JOURNAL/2026/2026-10-15]]"
priority: 10
description: "Choix du bridge opencode-chat-bridge (FluffyChat ⇄ Tuwunel ⇄ ACP) ; alternatives écartées."
---
sso# Installation — Bridge OpenCode ↔ Matrix (Fluffychat)

## Contexte

Objectif : discuter avec **OpenCode** depuis **Fluffychat** (client Matrix) via le homeserver **Matrix Tuwunel** (`matrix.datagrandest.net`, hébergé sur le même VPS). Le canal conversationnel Matrix est le choix retenu pour le projet [[03_PROJETS/VPS-IA]] (préféré à Telegram/WhatsApp).

## Choix retenu

**`opencode-chat-bridge`** (https://github.com/ominiverdi/opencode-chat-bridge) — le bridge Matrix le plus complet et actif pour OpenCode (connecteurs Matrix, Slack, Mattermost, WhatsApp, Discord, Telegram, Web ; E2EE Matrix, isolation par thread, permissions par agent). Alternatives écartées : **Kimaki** (Discord uniquement), bot maison via SDK OpenCode (trop de travail pour ce besoin).

**Architecture** :

```
Fluffychat (@shizendo) ⇄ Matrix Tuwunel ⇄ opencode-chat-bridge ⇄ opencode acp (ACP)
```

Le bridge **n'utilise pas** le service `opencode.service` existant : il lance son **propre `opencode acp`** par discussion, avec un agent dédié `chat-bridge` aux permissions restreintes (sécurité par isolation, appliquée par OpenCode au niveau exécution).

## Installation réalisée (2026-10-15)

Environnement : utilisateur `opencode` (HOME=/var/lib/opencode), Debian 12, pas de root pour l'agent → install utilisateur + unité systemd à activer en root.

| Élément | Valeur |
|---|---|
| Runtime Bun | `~/.bun/bin/bun` (v1.4.3) — requis par le bridge (Node 22+ déjà OK : v24) |
| Dépôt | `/var/lib/opencode/opencode-chat-bridge` (clone GitHub + `bun install`) |
| Compte bot Matrix | `@bot:matrix.datagrandest.net` (créé par l'utilisateur, connecté dans Fluffychat) |
| Secret | `opencode/matrix-bot-password` dans le coffre **pass** (jamais en clair) |
| Fichier `.env` | credentials Matrix + `MATRIX_ALLOWED_USERS` (perm. 600) |
| Config bridge | `chat-bridge.json` : connecteur Matrix, E2EE, `threadIsolation: false` (salon = session), `sessionPicker` activé, trigger `!oc`, `formatHtml` |
| Config OpenCode | `opencode.json` : agent `chat-bridge` + **modèle explicite** `openrouter/deepseek/deepseek-v4-flash-0731` |
| Stockage | `~/.local/share/opencode-matrix-bot/` (token, crypto E2EE, sessions) |

### Config `.env` (résumé — valeur sensible dans le coffre pass)

```bash
MATRIX_HOMESERVER=https://matrix.datagrandest.net
MATRIX_USER_ID=@bot:matrix.datagrandest.net
MATRIX_PASSWORD=$(pass show opencode/matrix-bot-password)   # injecté à l'install, jamais affiché
MATRIX_TRIGGER=!oc
MATRIX_ALLOWED_USERS=@shizendo:matrix.datagrandest.net
SESSION_BASE_DIR=/var/lib/opencode/.local/share/opencode-matrix-bot
```

> ⚠️ Le bridge **ne charge pas `.env` automatiquement** → le service systemd le charge via `EnvironmentFile`.

### Config `opencode.json` (copié dans chaque répertoire de session)

- `model: openrouter/deepseek/deepseek-v4-flash-0731` (obligatoire, cf. incidents)
- `default_agent: chat-bridge`
- Agent `chat-bridge` : **permissions complètes** (`read, glob, grep, edit, write, bash, task, todowrite, todoread, webfetch, codesearch, skill, question` en `allow`) — choix **« B : assoupli sans validation »** (2026-10-16). Guillaume est seul utilisateur (allowlist `@shizendo`) ; garde-fou = le prompt de l'agent (annoncer les opérations destructrices), **non enforce**.
- **MCP activés pour le bot** (2026-10-16) : `silverbullet-ai` (lecture notes → tokens `SB_AUTH_TOKEN`), `grist` (`GRIST_API_KEY`) , `excalidraw-maaker` (génération diagrammes), `excalidraw` (canvas dédié **port 3002** pour éviter le conflit avec le canvas principal du service OpenCode sur 3001). Secrets injectés dans `.env` (600) depuis le coffre pass, jamais en clair.

## Procédure d'installation pas-à-pas

```bash
# 1. Installer Bun (runtime requis par le bridge ; Node 22+ déjà présent)
curl -fsSL https://bun.sh/install | HOME=/var/lib/opencode bash

# 2. Cloner + dépendances
git clone https://github.com/ominiverdi/opencode-chat-bridge /var/lib/opencode/opencode-chat-bridge
cd /var/lib/opencode/opencode-chat-bridge
HOME=/var/lib/opencode PATH=/var/lib/opencode/.bun/bin:$PATH bun install

# 3. Créer le compte bot Matrix (@bot:matrix.datagrandest.net) sur le homeserver

# 4. Insérer le mot de passe du bot dans le coffre pass (jamais en clair)
sudo -u opencode /var/lib/opencode/.local/bin/pass insert opencode/matrix-bot-password

# 5. Créer les 3 fichiers de config (contenus cf. sections suivantes) :
#    .env (600), chat-bridge.json, opencode.json

# 6. Test en avant-plan
cd /var/lib/opencode/opencode-chat-bridge
set -a; . ./.env; set +a
bun connectors/matrix.ts

# 7. Passer en service systemd (root) — unité : deploy/opencode-matrix.service
sudo cp deploy/opencode-matrix.service /etc/systemd/system/
sudo systemctl daemon-reload && sudo systemctl enable --now opencode-matrix
```

> **Points bloquants à connaître** (cf. Incidents) :
> - `MATRIX_ALLOWED_USERS` = l'ID Matrix de l'utilisateur (**`@shizendo:...`**, pas le pseudo SilverBullet `@grk`)
> - **modèle OpenCode explicite** dans `opencode.json` (sinon le défaut est bloqué par les guardrails OpenRouter)
> - après changement de modèle : **purger `.opencode/chat-sessions.json`** (`{"version":1,"sessions":[]}`) sinon la session ACP existante garde l'ancien modèle
> - ne **jamais lancer 2 instances** du bridge en parallèle (conflit de sync sur le token du bot)

## Incidents rencontrés & résolutions

1. **Messages ignorés** — `MATRIX_ALLOWED_USERS` initialisé à `@grk:...` mais l'ID Matrix de l'utilisateur est **`@shizendo:matrix.datagrandest.net`**. Corrigé dans `.env` + redémarrage.
2. **Erreurs de déchiffrement E2EE** — le connecteur active **toujours** la crypto Rust (indépendant de `encryption.enabled`). Les salons existants (créés via Fluffychat avec le compte bot) ont un historique que le nouveau device du bridge ne peut pas déchiffrer. **Bruit attendu, non fatal** (les nouveaux messages se déchiffrent, key-sharing OK).
3. **« Sorry, something went wrong »** — le backend ACP choisissait un **modèle par défaut bloqué par les guardrails OpenRouter** (`Model blocked by guardrail`). **Fix : modèle explicite** `openrouter/deepseek/deepseek-v4-flash-0731` dans `opencode.json`, puis **purge de la session ACP** (`.opencode/chat-sessions.json` → `{"version":1,"sessions":[]}`) pour repartir sur une session neuve.
4. **« 1 appareil non vérifié » dans Fluffychat** — device du bridge `wJUe7SVWmt` (display name « OpenCode Chat Bridge »). Le bridge (lib `matrix-bot-sdk`) n'implémente **ni la vérification interactive SAS (émoticônes) ni le cross-signing/self-signing** (limite connue de la lib, cf. matrix-hookshot #1001) → l'appareil restera non vérifié dans les salons chiffrés. **Cosmétique et non bloquant** : le partage de clés fonctionne (le bot déchiffre et répond). Options :
   - **ignorer l'avertissement** (recommandé — comportement des autres utilisateurs du bridge)
   - **salon non chiffré** pour le chat avec le bot (aucun avertissement ; DM Fluffychat = toujours chiffré, préférer un salon de groupe sans chiffrement)
   - **Element** (client) permet de marquer l'appareil « fiable » manuellement (trust local, sans SAS) — pas disponible dans Fluffychat
   - le **self-signing** type mautrix/openclaw n'existe pas ici → à demander en feature (issue GitHub upstream)

## Service systemd (actif depuis 2026-10-16)

Unité préparée dans le dépôt : `deploy/opencode-matrix.service` (user `opencode`, `EnvironmentFile=.env`, limites mémoire 1,5G/2G). Service **activé et vérifié** : `systemctl status opencode-matrix` → `active (running)`, une seule instance (ne pas lancer d'autre bridge en parallèle).

```bash
sudo cp /var/lib/opencode/opencode-chat-bridge/deploy/opencode-matrix.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now opencode-matrix
sudo systemctl status opencode-matrix
# logs
journalctl -u opencode-matrix -f
```

> Service **actif** (2026-10-16) — process de test arrêté.

## Utilisation

- **Salle/DM** : `!oc <requête>` (en DM le préfixe est optionnel)
- **Mention** : `@bot:matrix.datagrandest.net <requête>`
- **Commandes** : `!oc /help`, `!oc /status`, `!oc /clear`
- **Pièces jointes entrantes** : ⚠️ **non supportées par le connecteur Matrix** (seuls les messages texte sont traités — `m.text`). Le bot peut en revanche **envoyer** des images dans le salon (résultats d'outils). Les pièces jointes entrantes ne sont supportées que par le connecteur Telegram.
- **Un salon = une session** (`threadIsolation: false`, depuis 2026-10-16) : chaque salon Matrix a sa **session OpenCode persistante**. Créer plusieurs salons thématiques pour des contextes indépendants ; reset d'un salon via `!oc /clear`.
- **Session Picker** (`sessionPicker.enabled: true`, connecteurs `["matrix"]`) : `!oc /p` (projets/workdirs), `!oc /s` (sessions sauvegardées), `!oc /s <n>` (reprendre), `!oc /m` (mirror), `!oc /r`, `!oc /d` — utile pour choisir un projet OpenCode ou reprendre une session, usage occasionnel.
- **Isolation par thread** : à activer (`threadIsolation: true`) pour repasser en session par fil.
- Le bot **rejoint automatiquement** les salons où il est invité

## Suivi

- [x] Bun installé, dépôt cloné, dépendances installées
- [x] Bot `@bot:matrix.datagrandest.net` opérationnel (test `!oc bonjour` OK)
- [x] Modèle explicite + purge session ACP (correction guardrails OpenRouter)
- [x] Secret `opencode/matrix-bot-password` dans le coffre pass
- [x] **Service systemd activé en root** (2026-10-16) : `opencode-matrix.service`
- [x] **Permissions assouplies (choix B)** + **salon = session** (`threadIsolation: false`) — 2026-10-16
- [x] **Session Picker activé** (`sessionPicker.enabled: true`, connecteurs `["matrix"]`) — 2026-10-16
- [x] **MCP activés pour le bot** (silverbullet-ai, grist, excalidraw-maaker, excalidraw@3002) + secrets injectés dans `.env` — 2026-10-16
- [x] Documentation SilverBullet (cette note, enrichie le 2026-10-16)
- [ ] Vérification device du bot (cosmétique, optionnel)
- [ ] (Option) Activer/limiter les MCP disponibles pour le bot
- [ ] (Option) Test en salon chiffré si besoin — **E2EE actif côté bridge** depuis le 08/11 (Rust crypto + store `crypto/matrix-sdk-crypto.sqlite3` vérifiés ; le test fonctionnel reste à mener)

## Synthèse comparative avec ZeroClaw (2026-11-08)

Deux bots cohabitent : `@bot` (ce bridge) et `@zc` (ZeroClaw, voir [[VPS-IA_ZeroClaw-Matrix-2026-11-08]]). Tableau de synthèse complet (granularité de session, clés, persistance, auto-join, E2EE, déclencheurs, nettoyage) dans cette note.

Points saillants :

- **Salon = session** ici (`threadIsolation: false`) ; ZeroClaw va plus loin : **salon × expéditeur** (`matrix_<canal>__<room>__<sender>`).
- **Auto-join** : natif ici (`autoJoin: true`), **absent chez ZC 0.8.7** → cron `*/2` dédié côté ZC.
- **E2EE** : actif des deux côtés — ici via Rust crypto (la clé `encryption.enabled` de `chat-bridge.json` est **morte**, jamais lue par le connecteur), chez ZC via `recovery_key`/SSSS.
