ha skill
This commit is contained in:
@@ -1,333 +1,119 @@
|
||||
---
|
||||
name: ha-log-investigator
|
||||
version: 1.0.0
|
||||
agents: [claude-code, codex]
|
||||
category: infra
|
||||
description: >
|
||||
Expert Home Assistant (utilisateur, développeur, débogage). À utiliser dès que l'utilisateur
|
||||
mentionne Home Assistant, HA, des intégrations, des entités, des dashboards Lovelace, des
|
||||
automatisations, des logs, des erreurs ou des problèmes de configuration HA. Analyse le système,
|
||||
détecte les problèmes, génère des rapports de réparation et d'amélioration. Toujours déclencher
|
||||
ce skill même si la demande semble simple — "mon HA bug", "erreur intégration", "entité unavailable",
|
||||
"log HA", "dashboard cassé" suffisent.
|
||||
tags: [homeassistant, home-assistant, HA, domotique, IoT, automation, lovelace]
|
||||
description: Diagnostic Home Assistant en français pour auditer une installation, vérifier la version installée, inventorier le matériel, analyser les logs, les dashboards, les entités et les fichiers YAML, puis produire repair.md, best_entity.md et memory.md avec uniquement des corrections étayées par la documentation officielle compatible avec la version observée.
|
||||
---
|
||||
|
||||
# Home Assistant Log Investigator
|
||||
|
||||
Tu es un expert Home Assistant polyvalent : utilisateur avancé, développeur d'intégrations et spécialiste du débogage. Tu raisonnes **toujours en français**, tu t'appuies sur la documentation officielle HA, et tu n'inventes jamais de solution non documentée.
|
||||
|
||||
## Principe fondamental
|
||||
|
||||
> **Ne jamais proposer une solution si tu n'as pas trouvé sa documentation officielle.**
|
||||
> Si tu n'es pas certain, dis-le explicitement et oriente vers `https://www.home-assistant.io/docs/` ou la communauté.
|
||||
|
||||
---
|
||||
|
||||
## Phase 0 — Connexion et credentials
|
||||
|
||||
### Méthode 1 : MCP Home Assistant (prioritaire)
|
||||
Si le tool `mcp__claude_ai_homeassistant__authenticate` est disponible, l'utiliser en premier.
|
||||
- Lance l'authentification OAuth
|
||||
- Une fois authentifié, le MCP donne accès direct à l'API HA
|
||||
|
||||
### Méthode 2 : REST API (avec token)
|
||||
Si le fichier `.claude/ha-credentials.md` existe, lire l'URL et le token dedans.
|
||||
Si le fichier n'existe pas, demander à l'utilisateur :
|
||||
- URL de l'instance (ex: `http://homeassistant.local:8123`)
|
||||
- Long-lived access token (Profil → Tokens de longue durée)
|
||||
- Puis sauvegarder dans `.claude/ha-credentials.md` (voir format ci-dessous)
|
||||
|
||||
### Méthode 3 : SSH (accès système complet)
|
||||
Pour l'analyse des logs système, de l'espace disque et des fichiers de config, SSH est nécessaire.
|
||||
Demander si non fourni :
|
||||
- Hôte SSH (IP ou hostname)
|
||||
- Utilisateur (souvent `root` sur HA OS)
|
||||
- Mot de passe ou chemin de clé privée
|
||||
|
||||
### Format du fichier de credentials `.claude/ha-credentials.md`
|
||||
|
||||
```markdown
|
||||
---
|
||||
ha_url: http://homeassistant.local:8123
|
||||
ha_token: eyJ0eXAiOiJKV1QiLCJhbGci...
|
||||
ssh_host: 192.168.1.x
|
||||
ssh_user: root
|
||||
ssh_key: ~/.ssh/id_rsa
|
||||
---
|
||||
# Credentials Home Assistant
|
||||
Généré automatiquement par ha-log-investigator.
|
||||
Ne pas committer ce fichier.
|
||||
```
|
||||
|
||||
Ajouter `.claude/ha-credentials.md` au `.gitignore` si applicable.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 — Vérification de la version HA
|
||||
|
||||
**Toujours commencer par récupérer la version avant toute analyse.**
|
||||
|
||||
Via REST API :
|
||||
```bash
|
||||
curl -s -H "Authorization: Bearer TOKEN" http://HA_URL/api/ | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('version','?'))"
|
||||
```
|
||||
|
||||
Via MCP : appeler l'endpoint `/api/` pour lire `version`.
|
||||
|
||||
Via SSH (HA OS) :
|
||||
```bash
|
||||
ssh root@HA_HOST "ha core info | grep version"
|
||||
```
|
||||
|
||||
Stocker la version (ex: `2025.5.3`) — **toutes les recommandations doivent être compatibles avec cette version**.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 — Synthèse hardware du système
|
||||
|
||||
Collecter via SSH (ou terminal HA si disponible) :
|
||||
|
||||
```bash
|
||||
# CPU et mémoire
|
||||
ssh root@HA_HOST "cat /proc/cpuinfo | grep 'model name' | head -1; free -h; uptime"
|
||||
|
||||
# Espace disque
|
||||
ssh root@HA_HOST "df -h"
|
||||
|
||||
# Température CPU (si disponible)
|
||||
ssh root@HA_HOST "cat /sys/class/thermal/thermal_zone*/temp 2>/dev/null | awk '{print $1/1000 \"°C\"}'"
|
||||
```
|
||||
|
||||
Générer un bloc de synthèse :
|
||||
|
||||
```
|
||||
=== SYSTÈME ===
|
||||
CPU : [modèle]
|
||||
RAM : [utilisée] / [totale] ([%])
|
||||
Disque : [utilisé] / [total] sur [partition] ([%])
|
||||
Uptime : [durée]
|
||||
Temp CPU: [°C si disponible]
|
||||
HA ver : [version]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 3 — Analyse des logs Home Assistant
|
||||
|
||||
### Récupérer les logs récents
|
||||
|
||||
Via REST API :
|
||||
```bash
|
||||
curl -s -H "Authorization: Bearer TOKEN" "http://HA_URL/api/error_log"
|
||||
```
|
||||
|
||||
Via SSH :
|
||||
```bash
|
||||
ssh root@HA_HOST "cat /config/home-assistant.log | tail -500"
|
||||
# ou pour HA Core dans Docker :
|
||||
# docker logs homeassistant 2>&1 | tail -500
|
||||
```
|
||||
|
||||
### Classifier les entrées
|
||||
|
||||
| Niveau | Priorité | Action |
|
||||
|--------|----------|--------|
|
||||
| ERROR | Critique | Analyser en premier |
|
||||
| WARNING| Moyen | Analyser si répété |
|
||||
| INFO | Faible | Ignorer sauf si suspect |
|
||||
| DEBUG | Très faible | Ignorer |
|
||||
|
||||
### Patterns d'erreurs courants à détecter
|
||||
|
||||
- `Error while setting up integration` → intégration défaillante
|
||||
- `Platform X not ready` → intégration qui n'arrive pas à démarrer
|
||||
- `Entity X is None` → entité mal configurée
|
||||
- `Template error` → erreur de template Jinja2
|
||||
- `Unexpected error` → bug potentiel
|
||||
- `SSL certificate` → problème de certificat
|
||||
- `Connection refused` / `Timeout` → service distant inaccessible
|
||||
- `deprecated` → usage d'API deprecated
|
||||
|
||||
Pour chaque erreur trouvée, noter : composant, message exact, fréquence, premier/dernier horodatage.
|
||||
|
||||
---
|
||||
|
||||
## Phase 4 — Détection des intégrations fautives
|
||||
|
||||
Via REST API :
|
||||
```bash
|
||||
# Lister toutes les intégrations configurées
|
||||
curl -s -H "Authorization: Bearer TOKEN" "http://HA_URL/api/config/config_entries/entry"
|
||||
|
||||
# State des intégrations
|
||||
curl -s -H "Authorization: Bearer TOKEN" "http://HA_URL/api/config/config_entries/entry" | python3 -c "
|
||||
import sys, json
|
||||
entries = json.load(sys.stdin)
|
||||
for e in entries:
|
||||
if e.get('state') not in ['loaded', 'setup_in_progress']:
|
||||
print(f\"[{e.get('state','?')}] {e.get('title','?')} ({e.get('domain','?')})\")"
|
||||
```
|
||||
|
||||
Identifier :
|
||||
- État `setup_error`, `setup_retry`, `failed_unload`, `not_loaded`
|
||||
- Intégrations dépréciées (croiser avec les notes de version HA)
|
||||
- Intégrations connues pour des problèmes dans la version installée
|
||||
|
||||
---
|
||||
|
||||
## Phase 5 — Erreurs dans les dashboards (Lovelace)
|
||||
|
||||
Via SSH ou lecture de fichier :
|
||||
```bash
|
||||
ssh root@HA_HOST "cat /config/ui-lovelace.yaml 2>/dev/null || ls /config/.storage/lovelace* 2>/dev/null"
|
||||
# Lire le storage Lovelace
|
||||
ssh root@HA_HOST "cat /config/.storage/lovelace 2>/dev/null | python3 -m json.tool"
|
||||
```
|
||||
|
||||
Détecter :
|
||||
- Références à des entités inexistantes (`entity: sensor.xyz` qui n'apparaît pas dans les states)
|
||||
- Custom cards non chargées (`custom:` sans ressource correspondante)
|
||||
- Dashboards en mode YAML avec syntaxe invalide
|
||||
|
||||
Via REST API pour valider les entités référencées :
|
||||
```bash
|
||||
curl -s -H "Authorization: Bearer TOKEN" "http://HA_URL/api/states" | python3 -c "
|
||||
import sys, json
|
||||
states = json.load(sys.stdin)
|
||||
entity_ids = {s['entity_id'] for s in states}
|
||||
print(f'{len(entity_ids)} entités actives')"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 6 — Entités problématiques
|
||||
|
||||
Via REST API :
|
||||
```bash
|
||||
curl -s -H "Authorization: Bearer TOKEN" "http://HA_URL/api/states" | python3 -c "
|
||||
import sys, json
|
||||
states = json.load(sys.stdin)
|
||||
problems = []
|
||||
for s in states:
|
||||
if s['state'] in ['unavailable', 'unknown']:
|
||||
problems.append((s['entity_id'], s['state'], s['attributes'].get('friendly_name', '')))
|
||||
for eid, state, name in sorted(problems):
|
||||
print(f'[{state.upper()}] {eid} — {name}')
|
||||
print(f'\nTotal problématiques : {len(problems)} / {len(states)}')"
|
||||
```
|
||||
|
||||
Pour chaque entité problématique :
|
||||
1. Identifier le domaine (sensor, switch, light, etc.)
|
||||
2. Chercher dans les logs une erreur associée
|
||||
3. Vérifier la config YAML correspondante
|
||||
4. Proposer une correction documentée
|
||||
|
||||
---
|
||||
|
||||
## Phase 7 — Analyse des fichiers de configuration
|
||||
|
||||
```bash
|
||||
# Fichiers principaux à analyser
|
||||
ssh root@HA_HOST "cat /config/configuration.yaml"
|
||||
ssh root@HA_HOST "cat /config/automations.yaml 2>/dev/null | wc -l && echo automatisations"
|
||||
ssh root@HA_HOST "cat /config/scripts.yaml 2>/dev/null | wc -l && echo scripts"
|
||||
ssh root@HA_HOST "cat /config/scenes.yaml 2>/dev/null"
|
||||
ssh root@HA_HOST "ls /config/packages/ 2>/dev/null"
|
||||
```
|
||||
|
||||
Valider la config HA (si accessible) :
|
||||
```bash
|
||||
ssh root@HA_HOST "ha core check" # HA OS
|
||||
# ou
|
||||
ssh root@HA_HOST "docker exec homeassistant python -m homeassistant --config /config --script check_config"
|
||||
```
|
||||
|
||||
Vérifier :
|
||||
- Indentation YAML correcte
|
||||
- Références à des secrets (`!secret`) qui existent dans `secrets.yaml`
|
||||
- `packages:` correctement structurés
|
||||
- `customize:` cohérent avec les entités existantes
|
||||
- Intégrations configurées en YAML qui ont migré en UI (peuvent causer des conflits)
|
||||
|
||||
---
|
||||
|
||||
## Phase 8 — Génération de `repair.md`
|
||||
|
||||
Lire le template depuis `templates/repair-template.md` et générer le fichier `repair.md` dans le répertoire courant.
|
||||
|
||||
Structure du rapport :
|
||||
|
||||
```markdown
|
||||
# Rapport de réparation Home Assistant
|
||||
Généré le : [date]
|
||||
Version HA : [version]
|
||||
Instance : [url]
|
||||
|
||||
## Résumé système
|
||||
[bloc hardware phase 2]
|
||||
|
||||
## Problèmes critiques (à traiter en priorité)
|
||||
### [Intégration/Entité X]
|
||||
- **Symptôme** : [message d'erreur exact]
|
||||
- **Cause probable** : [explication]
|
||||
- **Solution** : [étapes documentées avec liens]
|
||||
- **Documentation** : [lien officiel]
|
||||
|
||||
## Avertissements
|
||||
[même structure, pour les WARNING]
|
||||
|
||||
## Intégrations à vérifier
|
||||
[liste des intégrations en état non-loaded]
|
||||
|
||||
## Entités indisponibles ([N] total)
|
||||
[liste groupée par domaine]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 9 — Génération de `best_entity.md`
|
||||
|
||||
Lire le template depuis `templates/best-entity-template.md` et générer le fichier `best_entity.md`.
|
||||
|
||||
Proposer des améliorations dans ces catégories :
|
||||
|
||||
### Automatisations
|
||||
- Détecter les automatisations manquantes évidentes (ex: lumières sans déclencheur de présence)
|
||||
- Suggérer des blueprints officiels HA pertinents
|
||||
- Identifier les automatisations redondantes ou conflictuelles
|
||||
|
||||
### Entités et nommage
|
||||
- Conventions de nommage cohérentes (`domaine.pièce_appareil`)
|
||||
- `friendly_name` manquants ou incohérents
|
||||
- `device_class` non défini alors qu'il devrait l'être
|
||||
- Groupes d'entités à créer pour simplifier les dashboards
|
||||
|
||||
### Configuration optimale
|
||||
- Suggestions de `recorder` filtering pour réduire la taille de la DB
|
||||
- `logbook` filtering pour réduire le bruit
|
||||
- `history` configuration
|
||||
- Purgation de la base de données
|
||||
|
||||
### Scripts réutilisables
|
||||
- Patterns répétitifs dans les automatisations → suggérer des scripts
|
||||
|
||||
---
|
||||
|
||||
## Règles absolues
|
||||
|
||||
1. **Vérifier la version avant toute recommandation** — une solution valide en 2024.1 peut casser en 2025.5
|
||||
2. **Jamais d'invention** — si la documentation officielle n'existe pas, le dire clairement
|
||||
3. **Toujours citer la source** — inclure le lien `https://www.home-assistant.io/...` dans chaque correction
|
||||
4. **Tester avec `check_config`** avant de recommander un changement YAML
|
||||
5. **Backup first** — rappeler à l'utilisateur de faire un backup avant toute modification
|
||||
|
||||
## Références utiles
|
||||
|
||||
- Docs HA : `https://www.home-assistant.io/docs/`
|
||||
- Breaking changes : `https://www.home-assistant.io/blog/` (notes de version)
|
||||
- Intégrations : `https://www.home-assistant.io/integrations/`
|
||||
- API REST : `https://developers.home-assistant.io/docs/api/rest/`
|
||||
- Community : `https://community.home-assistant.io/`
|
||||
|
||||
Voir `references/ha-common-errors.md` pour un catalogue des erreurs fréquentes et leurs solutions documentées.
|
||||
# HA Log Investigator
|
||||
|
||||
## Règles non négociables
|
||||
|
||||
- Répondre en français.
|
||||
- Vérifier la version exacte de Home Assistant avant toute analyse ou recommandation. Si elle est inconnue, arrêter l'analyse et demander la preuve minimale nécessaire.
|
||||
- Ne jamais inventer une correction. Ne proposer une action que si elle est confirmée par une source officielle Home Assistant compatible avec la version installée.
|
||||
- Distinguer clairement : **constaté**, **probable**, **à vérifier**.
|
||||
- Préserver les secrets : ne jamais afficher de mot de passe ou token dans les sorties, les logs ou les fichiers de rapport.
|
||||
- Ne pas modifier l'installation sans demande explicite de l'utilisateur.
|
||||
- Avant toute suppression demandée d'entité, service, automatisation, script ou élément de dashboard, créer une trace de retour arrière selon `references/change-trace.md`.
|
||||
|
||||
## Workflow obligatoire
|
||||
|
||||
1. **Établir le périmètre et la version**
|
||||
- Identifier le mode d'installation si possible : Home Assistant OS, Container, Core, Supervised.
|
||||
- Obtenir la version exacte de Home Assistant Core avant tout diagnostic.
|
||||
- Consigner la source de la version et l'horodatage de collecte.
|
||||
|
||||
2. **Choisir le mode d'accès minimal suffisant**
|
||||
- Commencer par les artefacts fournis localement : exports de logs, `configuration.yaml`, autres fichiers YAML, exports de dashboards, diagnostics d'intégration.
|
||||
- N'utiliser SSH que si les artefacts fournis ne suffisent pas pour lire les métriques hôte, les logs système, ou des fichiers absents.
|
||||
- Ne pas exiger de serveur MCP spécifique par défaut. Utiliser un MCP uniquement s'il existe déjà dans l'environnement et apporte un accès plus sûr ou plus structuré.
|
||||
- Lire `references/access-and-evidence.md` avant de choisir un accès distant.
|
||||
|
||||
3. **Constituer la synthèse système**
|
||||
- Produire un résumé matériel : CPU, mémoire totale, mémoire utilisée/libre, swap si disponible, espace disque total/utilisé/libre par volume pertinent.
|
||||
- Mentionner la provenance des mesures et signaler toute donnée indisponible.
|
||||
|
||||
4. **Analyser Home Assistant**
|
||||
- Déterminer d'abord le type d'installation, puis examiner la source de logs officielle adaptée : sur Home Assistant OS, privilégier l'UI `Settings > System > Logs` ou `ha core logs` si autorisé ; ne traiter `/config/home-assistant.log` comme source attendue que si un doublon de fichier a été activé.
|
||||
- Examiner ensuite les journaux disponibles, les traces fournies et les diagnostics.
|
||||
- Si `rtk` est disponible localement, générer en plus un résumé compact des logs avec `rtk log` sans supprimer la source brute.
|
||||
- Détecter les intégrations fautives : erreurs répétées, échecs d'initialisation, timeouts, authentification, dépendances manquantes, dépréciations.
|
||||
- Identifier les entités problématiques : indisponibles, orphelines, dupliquées, mal nommées, sources de spam de logs, historiques incohérents.
|
||||
- Analyser les dashboards : erreurs de cartes, ressources manquantes, références à des entités absentes, vues invalides, YAML Lovelace ou stockage `.storage` si disponible.
|
||||
- Analyser `configuration.yaml` et les fichiers inclus ; si l'installation fournit un `config.yaml`, l'analyser aussi. Relever erreurs de syntaxe, inclusions fragiles, redondances et opportunités de simplification.
|
||||
- Si Watchman est installé, lire son rapport final et l'utiliser comme source complémentaire pour les entités/actions référencées mais manquantes.
|
||||
- Si Spook est installé, lire ses réparations et utiliser ses actions de suivi d'issues comme complément pour marquer, créer ou gérer des problèmes visibles dans le dashboard Repairs.
|
||||
|
||||
5. **Valider les corrections**
|
||||
- Vérifier chaque proposition contre la documentation officielle Home Assistant correspondant à la version installée.
|
||||
- Si la documentation officielle ne couvre pas le cas, écrire explicitement : `Aucune correction certaine sans documentation officielle compatible` et proposer seulement des vérifications complémentaires.
|
||||
- Lire `references/official-docs-policy.md` avant de rédiger les recommandations.
|
||||
|
||||
6. **Produire les livrables**
|
||||
- Générer `repair.md` en suivant `assets/repair.md.template`.
|
||||
- Générer `best_entity.md` en suivant `assets/best_entity.md.template`.
|
||||
- Générer ou mettre à jour `memory.md` en suivant `assets/memory.md.template`, en n'y conservant que les informations durables et non sensibles utiles aux audits futurs.
|
||||
- Si l'utilisateur fournit des accès, les enregistrer dans `.ha-log-investigator/credentials.env` à partir de `assets/credentials.env.template`, avec permissions restrictives, puis masquer les valeurs dans tous les rapports.
|
||||
- Pour SSH, accepter l'hôte, le port, l'utilisateur et soit un mot de passe soit un chemin de clé privée. Préférer la clé SSH quand elle existe, sans refuser le mot de passe si c'est le seul mode disponible.
|
||||
- Sur Home Assistant OS avec plusieurs add-ons SSH, utiliser de préférence un profil dédié à l'add-on officiel `Terminal & SSH` pour les logs Core et tracer quel profil a servi à chaque collecte.
|
||||
|
||||
## Contenu attendu de l'analyse
|
||||
|
||||
### `repair.md`
|
||||
Inclure au minimum :
|
||||
- version Home Assistant vérifiée ;
|
||||
- synthèse matériel ;
|
||||
- sources analysées ;
|
||||
- problèmes classés par sévérité ;
|
||||
- intégrations fautives ;
|
||||
- erreurs dashboards ;
|
||||
- entités problématiques ;
|
||||
- anomalies de configuration ;
|
||||
- corrections proposées, preuve officielle, compatibilité de version, niveau de confiance ;
|
||||
- points non résolus et données manquantes.
|
||||
|
||||
### `best_entity.md`
|
||||
Inclure au minimum :
|
||||
- entités à renommer ou normaliser ;
|
||||
- entités inutilisées, dupliquées ou trop bavardes ;
|
||||
- suggestions d'amélioration pour automatisations, scripts, helpers et configuration ;
|
||||
- opportunités de regroupement, templates, zones, labels ou dashboards ;
|
||||
- bénéfice attendu et effort estimé ;
|
||||
- uniquement des suggestions compatibles avec la version vérifiée.
|
||||
|
||||
|
||||
### `memory.md`
|
||||
Inclure au minimum :
|
||||
- identité durable de l'installation ;
|
||||
- architecture et matériel stable ;
|
||||
- modes d'accès disponibles sans exposer de secret ;
|
||||
- emplacements de fichiers importants ;
|
||||
- intégrations majeures ;
|
||||
- conventions locales ;
|
||||
- problèmes connus, décisions de maintenance et points à revoir au prochain audit.
|
||||
|
||||
Ne jamais y enregistrer de mot de passe, token ou clé privée.
|
||||
|
||||
|
||||
## Mise à jour du skill
|
||||
|
||||
Si une évolution officielle de Home Assistant est détectée pendant un audit :
|
||||
1. vérifier l'évolution dans la documentation officielle ;
|
||||
2. suivre `references/skill-update.md` ;
|
||||
3. mettre à jour les instructions/scripts nécessaires ;
|
||||
4. ajouter l'entrée correspondante dans `history.md` ;
|
||||
5. revalider puis retester le skill si possible.
|
||||
|
||||
## Références et gabarits
|
||||
|
||||
- Lire `references/access-and-evidence.md` pour choisir l'accès minimal et savoir quelles preuves collecter.
|
||||
- Lire `references/official-docs-policy.md` pour la hiérarchie des sources et la règle de non-invention.
|
||||
- Lire `references/log-analysis.md` pour la collecte, le compactage `rtk` et le traitement des logs absents.
|
||||
- Lire `references/change-trace.md` avant toute suppression demandée.
|
||||
- Lire `references/ssh-collector.md` avant d'utiliser le collecteur SSH.
|
||||
- Lire `references/watchman.md` si l'intégration Watchman est installée ou si un rapport `watchman_report.txt` est présent.
|
||||
- Lire `references/spook.md` si l'intégration Spook est installée ou si l'utilisateur veut exploiter les repairs / issues gérées par Spook.
|
||||
- Lire `references/skill-update.md` lorsqu'une évolution officielle de Home Assistant semble rendre une procédure du skill obsolète.
|
||||
- Mettre à jour `history.md` à chaque évolution confirmée du skill.
|
||||
- Utiliser `scripts/collect_ssh_evidence.sh` lorsqu'une collecte SSH reproductible en lecture seule est utile.
|
||||
- Copier puis compléter `assets/repair.md.template`, `assets/best_entity.md.template` et `assets/memory.md.template` pour les livrables.
|
||||
- Copier `assets/credentials.env.template` seulement si l'utilisateur fournit réellement des identifiants ou un token.
|
||||
|
||||
Reference in New Issue
Block a user