Initial commit
This commit is contained in:
15
.claude-plugin/plugin.json
Normal file
15
.claude-plugin/plugin.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "doc",
|
||||
"description": "Documentation : ADR, RTFM, génération docs, framework docs avec skills spécialisés",
|
||||
"version": "1.1.0",
|
||||
"author": {
|
||||
"name": "Aurélien Tournayre",
|
||||
"email": "aurelien.tournayre@gmail.com"
|
||||
},
|
||||
"skills": [
|
||||
"./skills"
|
||||
],
|
||||
"commands": [
|
||||
"./commands"
|
||||
]
|
||||
}
|
||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# doc
|
||||
|
||||
Documentation : ADR, RTFM, génération docs, framework docs avec skills spécialisés
|
||||
110
commands/adr.md
Normal file
110
commands/adr.md
Normal file
@@ -0,0 +1,110 @@
|
||||
---
|
||||
model: claude-opus-4-1-20250805
|
||||
allowed-tools: Read, Write, Edit, Bash
|
||||
argument-hint: [titre]
|
||||
description: Génère un Architecture Decision Record (ADR) formaté et structuré
|
||||
---
|
||||
|
||||
# Génération d'ADR
|
||||
|
||||
## Purpose
|
||||
Génère un Architecture Decision Record (ADR) complet et structuré pour documenter les décisions architecturales importantes du projet.
|
||||
|
||||
## Variables
|
||||
- **DECISION_TITLE**: Le titre de la décision architecturale
|
||||
- **DECISION_NUMBER**: Le numéro séquentiel de l'ADR (auto-généré si non fourni)
|
||||
|
||||
## Instructions
|
||||
- Si `TITRE` n'est pas fourni, ARRETER immediatement et demander à l'utilisateur de le fournir.
|
||||
- Crée un ADR suivant le format standard RFC
|
||||
- Utilise la numérotation séquentielle automatique
|
||||
- Intègre le contexte du projet actuel
|
||||
- Respecte les conventions de documentation du projet
|
||||
|
||||
## Relevant Files
|
||||
- `docs/adr/` - Dossier contenant les ADR existants
|
||||
- `docs/adr/README.md` - Liste des ADR existants
|
||||
- `docs/README.md` - Contexte général du projet
|
||||
- `CLAUDE.md` - Conventions et préférences
|
||||
|
||||
## Codebase Structure
|
||||
```
|
||||
docs/
|
||||
adr/
|
||||
0001-use-php-for-backend.md
|
||||
0002-implement-elegant-objects.md
|
||||
README.md
|
||||
```
|
||||
|
||||
## Workflow
|
||||
|
||||
- Analyse les ADR existants pour déterminer le prochain numéro
|
||||
- Examine le projet pour comprendre le contexte architectural
|
||||
- Crée un nouveau fichier ADR avec la numérotation appropriée
|
||||
- Utilise le template standardisé avec les sections requises
|
||||
- Valide la cohérence avec les décisions précédentes
|
||||
|
||||
## Expertise
|
||||
- Architecture logicielle et patterns de conception
|
||||
- Documentation technique et ADR standards
|
||||
- Conventions de nommage et organisation des documents
|
||||
- Principles DDD et Elegant Objects (selon le contexte du projet)
|
||||
|
||||
## Template
|
||||
```markdown
|
||||
# ADR-XXXX: [Titre de la décision]
|
||||
|
||||
## Statut
|
||||
- **Statut**: [Proposé | Accepté | Rejeté | Déprécié | Remplacé par ADR-YYYY]
|
||||
- **Date**: YYYY-MM-DD
|
||||
- **Auteurs**: [Noms]
|
||||
- **Reviewers**: [Noms]
|
||||
|
||||
## Contexte
|
||||
[Description du problème ou de la situation qui nécessite une décision]
|
||||
|
||||
## Décision
|
||||
[La décision prise et sa justification]
|
||||
|
||||
## Conséquences
|
||||
### Positives
|
||||
- [Bénéfices attendus]
|
||||
|
||||
### Négatives
|
||||
- [Coûts et risques identifiés]
|
||||
|
||||
### Neutres
|
||||
- [Autres implications]
|
||||
|
||||
## Alternatives considérées
|
||||
### Option 1: [Nom]
|
||||
- **Avantages**: [Liste]
|
||||
- **Inconvénients**: [Liste]
|
||||
- **Raison du rejet**: [Explication]
|
||||
|
||||
### Option 2: [Nom]
|
||||
- **Avantages**: [Liste]
|
||||
- **Inconvénients**: [Liste]
|
||||
- **Raison du rejet**: [Explication]
|
||||
|
||||
## Références
|
||||
- [Liens vers documentation, discussions, tickets]
|
||||
|
||||
## Notes d'implémentation
|
||||
[Détails techniques spécifiques pour l'implémentation]
|
||||
```
|
||||
|
||||
## Examples
|
||||
```bash
|
||||
# Génération d'un ADR pour l'adoption d'un nouveau framework
|
||||
/adr "Adoption du framework Symfony pour l'API"
|
||||
|
||||
# Génération d'un ADR pour une décision de base de données
|
||||
/adr "Migration vers PostgreSQL pour les performances"
|
||||
```
|
||||
|
||||
## Report
|
||||
- Affiche le numéro ADR généré
|
||||
- Confirme la création du fichier dans `docs/adr/`
|
||||
- Liste les fichiers ADR existants pour référence
|
||||
- Rappelle les prochaines étapes (review, validation)
|
||||
6
commands/framework-load.md
Normal file
6
commands/framework-load.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
description: Charge la documentation d'un framework depuis son site web dans des fichiers markdown locaux
|
||||
argument-hint: <framework-name> [version]
|
||||
---
|
||||
|
||||
You must use the Skill tool to invoke the "doc-loader" skill with the following arguments.
|
||||
102
commands/framework-question.md
Normal file
102
commands/framework-question.md
Normal file
@@ -0,0 +1,102 @@
|
||||
---
|
||||
allowed-tools: [Read, Grep, Glob, Bash]
|
||||
description: Interroger la documentation locale d'un framework pour répondre à une question
|
||||
argument-hint: <framework-name> [version] <question>
|
||||
model: claude-sonnet-4-5-20250929
|
||||
---
|
||||
|
||||
# Interrogation Documentation Framework
|
||||
|
||||
Répondre à une question technique sur un framework en utilisant sa documentation locale.
|
||||
|
||||
{{_templates/timing.md}}
|
||||
|
||||
## Frameworks Supportés
|
||||
|
||||
- `symfony`
|
||||
- `api-platform`
|
||||
- `meilisearch`
|
||||
- `atournayre-framework`
|
||||
|
||||
## Variables
|
||||
|
||||
- FRAMEWORK: Nom du framework (1er argument)
|
||||
- VERSION: Version optionnelle (2ème argument si fourni)
|
||||
- QUESTION: Question technique (dernier argument)
|
||||
- DOCS_PATH: `docs/${FRAMEWORK}/${VERSION}/` (ou `docs/${FRAMEWORK}/` si pas de version)
|
||||
|
||||
## Parsing Arguments
|
||||
|
||||
Détecter automatiquement si VERSION fournie :
|
||||
- 2 args : `<framework> <question>` → pas de version
|
||||
- 3+ args : `<framework> <version> <question>` → version fournie
|
||||
- Si 2ème arg ressemble version (chiffres+points) : VERSION
|
||||
- Sinon : partie de QUESTION
|
||||
|
||||
## Validation
|
||||
|
||||
Si FRAMEWORK non supporté ou QUESTION vide :
|
||||
- Afficher usage correct
|
||||
- Arrêter l'exécution
|
||||
|
||||
## Workflow
|
||||
|
||||
### Étape 1: Vérification documentation
|
||||
- Parser arguments (framework, version opt, question)
|
||||
- Construire DOCS_PATH selon présence version
|
||||
- Vérifier existence de `DOCS_PATH`
|
||||
- Si absent : suggérer `/doc:framework:load ${FRAMEWORK} [${VERSION}]`
|
||||
- Si version absente mais multiples versions existent : lister versions disponibles
|
||||
|
||||
### Étape 2: Analyse question
|
||||
- Extraire mots-clés de QUESTION
|
||||
- Identifier contexte technique
|
||||
|
||||
### Étape 3: Recherche
|
||||
- Grep avec mots-clés dans DOCS_PATH
|
||||
- Paramètres : `-i -C 3`
|
||||
- Lire fichiers pertinents
|
||||
|
||||
### Étape 4: Synthèse
|
||||
- Extraire sections pertinentes
|
||||
- Organiser par pertinence
|
||||
- Identifier : concept, exemples, bonnes pratiques
|
||||
|
||||
### Étape 5: Réponse
|
||||
|
||||
```markdown
|
||||
## 📚 Réponse : [Sujet] ([Framework] [version])
|
||||
|
||||
### Concept
|
||||
- Explication
|
||||
- Points clés
|
||||
|
||||
### Exemple Code
|
||||
[Si disponible]
|
||||
|
||||
### Documentation Référence
|
||||
- 📄 `docs/${FRAMEWORK}/[version]/[fichier].md`
|
||||
|
||||
### Voir Aussi
|
||||
- Concepts connexes
|
||||
```
|
||||
|
||||
## Gestion Erreurs
|
||||
|
||||
- **Doc manquante** : Suggérer `/doc:framework:load ${FRAMEWORK} [version]`
|
||||
- **Versions multiples** : Lister versions + demander précision
|
||||
- **Aucun résultat** : Termes alternatifs
|
||||
- **Question vague** : Demander précisions
|
||||
|
||||
## Exemples
|
||||
|
||||
```bash
|
||||
# Sans version (cherche dans toutes versions ou latest)
|
||||
/doc:framework:question symfony "Comment créer un controller ?"
|
||||
/doc:framework:question api-platform "Configurer sérialisation"
|
||||
|
||||
# Avec version spécifique
|
||||
/doc:framework:question symfony 6.4 "Comment créer un controller ?"
|
||||
/doc:framework:question api-platform 3.2 "Configurer sérialisation"
|
||||
/doc:framework:question meilisearch 1.5 "Ajouter des filtres"
|
||||
```
|
||||
65
commands/rtfm.md
Normal file
65
commands/rtfm.md
Normal file
@@ -0,0 +1,65 @@
|
||||
---
|
||||
model: claude-sonnet-4-5-20250929
|
||||
allowed-tools: Bash, WebFetch, WebSearch
|
||||
argument-hint: [url|doc-name]
|
||||
description: Lit la documentation technique - RTFM (Read The Fucking Manual)
|
||||
---
|
||||
|
||||
# Documentation Reader - RTFM
|
||||
|
||||
## Purpose
|
||||
Force Claude à lire et comprendre la documentation technique fournie, que ce soit via une URL directe ou en recherchant une documentation par nom.
|
||||
|
||||
## Variables
|
||||
DOC_SOURCE: L'URL ou le nom de la documentation à lire
|
||||
|
||||
## Instructions
|
||||
- Si une URL est fournie directement, utilise WebFetch pour la lire
|
||||
- Si un nom de documentation est fourni, utilise WebSearch pour la trouver puis WebFetch pour la lire
|
||||
- Force Claude à lire complètement la documentation avant de répondre
|
||||
- Fournis un résumé structuré des points clés
|
||||
|
||||
## Relevant Files
|
||||
- Documentation externe via WebFetch/WebSearch
|
||||
|
||||
## Codebase Structure
|
||||
Cette commande ne modifie pas le codebase, elle lit uniquement la documentation externe.
|
||||
|
||||
## Workflow
|
||||
|
||||
- Si DOC_SOURCE commence par http/https, utilise directement WebFetch
|
||||
- Sinon, recherche la documentation avec WebSearch puis lis le résultat avec WebFetch
|
||||
- Parse et structure l'information de la documentation
|
||||
- Fournis un résumé concis et actionnable
|
||||
|
||||
## Expertise
|
||||
- Lecture et analyse de documentation technique
|
||||
- Extraction d'informations clés
|
||||
- Synthèse et structuration de contenu
|
||||
|
||||
## Template
|
||||
```
|
||||
# Documentation: [NOM]
|
||||
|
||||
## Résumé
|
||||
[Résumé concis en 2-3 phrases]
|
||||
|
||||
## Points clés
|
||||
- Point important 1
|
||||
- Point important 2
|
||||
- Point important 3
|
||||
|
||||
## Exemples pratiques
|
||||
[Exemples d'usage si disponibles]
|
||||
|
||||
## Liens utiles
|
||||
[Références additionnelles si pertinentes]
|
||||
```
|
||||
|
||||
## Examples
|
||||
- `/rtfm https://docs.anthropic.com/claude/reference` - Lit directement la documentation Claude
|
||||
- `/rtfm symfony doctrine` - Recherche et lit la documentation Symfony Doctrine
|
||||
- `/rtfm php 8.3 new features` - Recherche les nouvelles fonctionnalités PHP 8.3
|
||||
|
||||
## Report
|
||||
Résumé structuré de la documentation lue avec points clés et exemples pratiques.
|
||||
117
commands/update.md
Normal file
117
commands/update.md
Normal file
@@ -0,0 +1,117 @@
|
||||
---
|
||||
model: claude-sonnet-4-5-20250929
|
||||
allowed-tools: [Bash, Read, Write, Edit, Glob, Grep]
|
||||
description: Crées la documentation pour la fonctionnalité en cours. Mets à jour le readme global du projet si nécessaire. Lie les documents entre eux pour ne pas avoir de documentation orpheline. La documentation est générée dans les répertoire de documentation du projet.
|
||||
---
|
||||
|
||||
# Documentation de fonctionnalité
|
||||
|
||||
Génère ou met à jour la documentation pour la fonctionnalité en cours de développement, en s'assurant que tous les documents sont liés et que le README principal est à jour.
|
||||
|
||||
## Purpose
|
||||
Maintenir une documentation cohérente, à jour et bien interconnectée pour le projet.
|
||||
|
||||
## Variables
|
||||
- CURRENT_BRANCH: Branche Git en cours
|
||||
- DOC_DIR: Répertoire de documentation du projet (détection automatique)
|
||||
- README_PATH: Chemin vers le README principal du projet
|
||||
- FEATURE_NAME: Nom de la fonctionnalité extraite de la branche et des modifications
|
||||
|
||||
## Relevant Files
|
||||
- `README.md` - Documentation principale du projet
|
||||
- `docs/` - Répertoire de documentation standard
|
||||
- Fichiers source de la fonctionnalité
|
||||
- Fichiers de tests associés
|
||||
|
||||
## Workflow
|
||||
|
||||
### 1. Analyse du contexte
|
||||
- Identifie la branche Git en cours (git branch --show-current)
|
||||
- Analyse les modifications de la branche :
|
||||
- Fichiers modifiés (git status)
|
||||
- Diff par rapport à main/master (git diff)
|
||||
- Commits de la branche (git log)
|
||||
- Extrait le nom de la fonctionnalité depuis :
|
||||
- Le nom de la branche (ex: feature/user-auth → User Authentication)
|
||||
- Les commits de la branche
|
||||
- Les prompts récents de la session
|
||||
- Détermine le répertoire de documentation :
|
||||
- Cherche `docs/`, `documentation/`, ou équivalent
|
||||
- Crée le répertoire si nécessaire
|
||||
- Identifie les informations clés :
|
||||
- Fichiers principaux modifiés
|
||||
- Tests associés
|
||||
- Dépendances ajoutées/modifiées
|
||||
|
||||
### 2. Génération de la documentation
|
||||
- Crée ou met à jour le fichier de documentation :
|
||||
- Titre et description claire
|
||||
- Utilisation et exemples
|
||||
- Architecture et composants
|
||||
- Configuration nécessaire
|
||||
- Tests et validation
|
||||
- Limitations et notes
|
||||
- Format Markdown structuré avec :
|
||||
- Table des matières si nécessaire
|
||||
- Blocs de code avec syntaxe
|
||||
- Liens vers fichiers sources
|
||||
- Exemples d'utilisation concrets
|
||||
|
||||
### 3. Mise à jour du README principal
|
||||
- Vérifie si la fonctionnalité doit être mentionnée dans le README
|
||||
- Ajoute ou met à jour la section appropriée :
|
||||
- Fonctionnalités principales
|
||||
- Structure du projet
|
||||
- Documentation disponible
|
||||
- Maintient la cohérence du format existant
|
||||
- Préserve l'ordre et la hiérarchie
|
||||
|
||||
### 4. Liaison des documents
|
||||
- Identifie les documents connexes :
|
||||
- Documentation de fonctionnalités liées
|
||||
- Guides d'architecture
|
||||
- Tutoriels
|
||||
- ADRs (Architecture Decision Records)
|
||||
- Ajoute des liens bidirectionnels :
|
||||
- Depuis le nouveau document vers les connexes
|
||||
- Depuis les connexes vers le nouveau document
|
||||
- Vérifie l'absence de liens cassés
|
||||
- Crée un index si nécessaire pour les projets volumineux
|
||||
|
||||
### 5. Validation et rapport
|
||||
- Vérifie la qualité de la documentation :
|
||||
- Tous les exemples sont fonctionnels
|
||||
- Les liens sont valides
|
||||
- Le formatage Markdown est correct
|
||||
- Pas de typos évidentes
|
||||
- Génère un rapport de ce qui a été créé/modifié
|
||||
|
||||
## Report
|
||||
Affiche un résumé structuré :
|
||||
|
||||
```
|
||||
Documentation générée :
|
||||
- Fonctionnalité : [NOM]
|
||||
- Fichier créé/modifié : [CHEMIN]
|
||||
- Taille : [LIGNES] lignes
|
||||
|
||||
Modifications README :
|
||||
- Section modifiée : [SECTION]
|
||||
- Ajouts : [DESCRIPTION]
|
||||
|
||||
Liens créés :
|
||||
- [DOC1] ↔ [DOC2]
|
||||
- [DOC3] ↔ [DOC4]
|
||||
|
||||
Documents liés :
|
||||
- [LISTE DES DOCS CONNEXES]
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
- Documentation focalisée sur l'utilisation, pas l'implémentation
|
||||
- Exemples concrets et testés
|
||||
- Langage clair et concis (style bullet points)
|
||||
- Liens relatifs pour la portabilité
|
||||
- Pas de duplication entre README et docs détaillées
|
||||
- README = vue d'ensemble, docs/ = détails
|
||||
- Maintenir la cohérence du ton et du format
|
||||
69
plugin.lock.json
Normal file
69
plugin.lock.json
Normal file
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"$schema": "internal://schemas/plugin.lock.v1.json",
|
||||
"pluginId": "gh:atournayre/claude-marketplace:doc",
|
||||
"normalized": {
|
||||
"repo": null,
|
||||
"ref": "refs/tags/v20251128.0",
|
||||
"commit": "eeabe26311f9a271d3c6afd9dbcc7a157d398332",
|
||||
"treeHash": "2ff2b912420398337ee829f53f0f7a59518de55e3677b86235c11fefda9a99dd",
|
||||
"generatedAt": "2025-11-28T10:14:00.426109Z",
|
||||
"toolVersion": "publish_plugins.py@0.2.0"
|
||||
},
|
||||
"origin": {
|
||||
"remote": "git@github.com:zhongweili/42plugin-data.git",
|
||||
"branch": "master",
|
||||
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
|
||||
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
|
||||
},
|
||||
"manifest": {
|
||||
"name": "doc",
|
||||
"description": "Documentation : ADR, RTFM, génération docs, framework docs avec skills spécialisés",
|
||||
"version": "1.1.0"
|
||||
},
|
||||
"content": {
|
||||
"files": [
|
||||
{
|
||||
"path": "README.md",
|
||||
"sha256": "3060ef8b0ea477f49b372a89dd49e8fe4074c705f6391fc9f1e2d7338bb6faa4"
|
||||
},
|
||||
{
|
||||
"path": ".claude-plugin/plugin.json",
|
||||
"sha256": "a46a7f45016552e05ec93718b9f3d05f24a641de75f990c63f4fb458e1588112"
|
||||
},
|
||||
{
|
||||
"path": "commands/framework-load.md",
|
||||
"sha256": "57786e9cd813b4a6e76525d60f5798f92985ac8998d873d7c465b76bcf04376f"
|
||||
},
|
||||
{
|
||||
"path": "commands/rtfm.md",
|
||||
"sha256": "2ebb4d0774032c911fbede387596aa243b8f20c177fa7f8c65e071690f136412"
|
||||
},
|
||||
{
|
||||
"path": "commands/framework-question.md",
|
||||
"sha256": "95b15c9b6e41af853e808ee8b3c2c8fd16f92e7b06b142729a5c5e80fd30912d"
|
||||
},
|
||||
{
|
||||
"path": "commands/update.md",
|
||||
"sha256": "c3dd12bf28017ec2d28bdb9967d4b2e23ab47c577059f69e0f99f9c000054e00"
|
||||
},
|
||||
{
|
||||
"path": "commands/adr.md",
|
||||
"sha256": "09daf6f4f4c26a0674b87cc17fee5dd32e004dc549aa7518f6fae9b7de5f9007"
|
||||
},
|
||||
{
|
||||
"path": "skills/doc-loader/README.md",
|
||||
"sha256": "627958fe5d4ebba963d6673cfdc42e7fdbf281e761e936a353bc84bd4dae2e44"
|
||||
},
|
||||
{
|
||||
"path": "skills/doc-loader/SKILL.md",
|
||||
"sha256": "5bc96c1db58357040583aa6a4c19c300ddd13312ad53655d270c4ff8b96da3e2"
|
||||
}
|
||||
],
|
||||
"dirSha256": "2ff2b912420398337ee829f53f0f7a59518de55e3677b86235c11fefda9a99dd"
|
||||
},
|
||||
"security": {
|
||||
"scannedAt": null,
|
||||
"scannerVersion": null,
|
||||
"flags": []
|
||||
}
|
||||
}
|
||||
100
skills/doc-loader/README.md
Normal file
100
skills/doc-loader/README.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Documentation Loader Skill
|
||||
|
||||
Charge la documentation de frameworks depuis leurs sites web dans des fichiers markdown locaux.
|
||||
|
||||
## Fonctionnalités
|
||||
|
||||
- Support multi-framework (Symfony, API Platform, Meilisearch, atournayre-framework, Claude Code)
|
||||
- Support multi-version (optionnel)
|
||||
- Gestion cache intelligent (24h)
|
||||
- Délégation aux agents scraper spécialisés
|
||||
- Anti-rate-limiting (délai 2s entre requêtes)
|
||||
- Statistiques détaillées (couverture, taille, fichiers)
|
||||
|
||||
## Usage
|
||||
|
||||
Via les commandes délégantes :
|
||||
```bash
|
||||
# Sans version (latest)
|
||||
/doc:framework-load symfony
|
||||
/symfony:doc:load
|
||||
/claude:doc:load
|
||||
|
||||
# Avec version spécifique
|
||||
/doc:framework-load symfony 6.4
|
||||
/doc:framework-load api-platform 3.2
|
||||
```
|
||||
|
||||
Ou directement via le skill :
|
||||
```bash
|
||||
# Utiliser l'outil Task avec le skill doc-loader
|
||||
```
|
||||
|
||||
## Frameworks Supportés
|
||||
|
||||
| Framework | Agent |
|
||||
|----------------------|-----------------------------------|
|
||||
| symfony | symfony-docs-scraper |
|
||||
| api-platform | api-platform-docs-scraper |
|
||||
| meilisearch | meilisearch-docs-scraper |
|
||||
| atournayre-framework | atournayre-framework-docs-scraper |
|
||||
| claude | claude-docs-scraper |
|
||||
|
||||
## Workflow
|
||||
|
||||
1. Parser arguments (framework + version optionnelle)
|
||||
2. Valider framework supporté
|
||||
3. Vérifier README avec liste URLs
|
||||
4. Gérer cache (ignorer fichiers récents < 24h, supprimer anciens)
|
||||
5. Pour chaque URL :
|
||||
- Déléguer à agent scraper spécialisé
|
||||
- Sauvegarder markdown
|
||||
- Délai 2s anti-rate-limit
|
||||
6. Rapport final avec statistiques
|
||||
|
||||
## Structure Fichiers
|
||||
|
||||
```
|
||||
docs/
|
||||
symfony/
|
||||
6.4/
|
||||
url1.md
|
||||
url2.md
|
||||
...
|
||||
api-platform/
|
||||
3.2/
|
||||
url1.md
|
||||
...
|
||||
claude/
|
||||
url1.md
|
||||
...
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
- `CACHE_HOURS`: 24h (fichiers plus anciens supprimés)
|
||||
- Délai entre URLs: 2s
|
||||
- README requis: `~/.claude/docs/<framework>/[version]/README.md`
|
||||
|
||||
## Rapport Généré
|
||||
|
||||
```yaml
|
||||
details:
|
||||
framework: "[nom]"
|
||||
version: "[version ou latest]"
|
||||
total_urls: [N]
|
||||
processed: [N]
|
||||
created: [N]
|
||||
errors: [N]
|
||||
statistics:
|
||||
documentation_files: [N]
|
||||
total_size: "[MB]"
|
||||
coverage: "[%]"
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Cache évite rechargements inutiles
|
||||
- Gestion erreurs non bloquante (continue si URL échoue)
|
||||
- Support version optionnel pour flexibilité
|
||||
- Délègue scraping aux agents spécialisés
|
||||
285
skills/doc-loader/SKILL.md
Normal file
285
skills/doc-loader/SKILL.md
Normal file
@@ -0,0 +1,285 @@
|
||||
---
|
||||
name: doc-loader
|
||||
description: >
|
||||
Charge la documentation d'un framework depuis son site web dans des fichiers markdown
|
||||
locaux. Supporte Symfony, API Platform, Meilisearch, atournayre-framework et Claude Code.
|
||||
Gère le cache, rate limiting et délègue aux agents scraper spécialisés.
|
||||
allowed-tools: [Task, WebFetch, Write, Edit, Bash, Read, Glob]
|
||||
model: claude-sonnet-4-5-20250929
|
||||
---
|
||||
|
||||
# Documentation Loader Skill
|
||||
|
||||
## Variables
|
||||
|
||||
```bash
|
||||
ARGUMENTS="$ARGUMENTS" # <framework> [version]
|
||||
FRAMEWORK=""
|
||||
VERSION=""
|
||||
DOCS_PATH=""
|
||||
README_PATH=""
|
||||
CACHE_HOURS=24
|
||||
AGENT_NAME=""
|
||||
```
|
||||
|
||||
## Frameworks Supportés
|
||||
|
||||
| Framework | Agent | Path |
|
||||
|---------------------|--------------------------------|-----------------------------------------|
|
||||
| symfony | symfony-docs-scraper | docs/symfony/[version]/ |
|
||||
| api-platform | api-platform-docs-scraper | docs/api-platform/[version]/ |
|
||||
| meilisearch | meilisearch-docs-scraper | docs/meilisearch/[version]/ |
|
||||
| atournayre-framework| atournayre-framework-docs-scraper | docs/atournayre-framework/[version]/ |
|
||||
| claude | claude-docs-scraper | docs/claude/ |
|
||||
|
||||
## Workflow
|
||||
|
||||
### Étape 0: Timing
|
||||
```bash
|
||||
START_TIME=$(date +%s)
|
||||
date
|
||||
```
|
||||
|
||||
### Étape 1: Parsing Arguments
|
||||
|
||||
```bash
|
||||
# Parser arguments
|
||||
ARGS=($ARGUMENTS)
|
||||
FRAMEWORK="${ARGS[0]}"
|
||||
VERSION="${ARGS[1]}" # Optionnel
|
||||
|
||||
# Validation framework
|
||||
case "$FRAMEWORK" in
|
||||
symfony|api-platform|meilisearch|atournayre-framework|claude)
|
||||
echo "✅ Framework: $FRAMEWORK"
|
||||
;;
|
||||
*)
|
||||
echo "❌ Framework non supporté: $FRAMEWORK"
|
||||
echo "Frameworks disponibles:"
|
||||
echo " - symfony"
|
||||
echo " - api-platform"
|
||||
echo " - meilisearch"
|
||||
echo " - atournayre-framework"
|
||||
echo " - claude"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Déterminer agent
|
||||
case "$FRAMEWORK" in
|
||||
symfony)
|
||||
AGENT_NAME="symfony-docs-scraper"
|
||||
;;
|
||||
api-platform)
|
||||
AGENT_NAME="api-platform-docs-scraper"
|
||||
;;
|
||||
meilisearch)
|
||||
AGENT_NAME="meilisearch-docs-scraper"
|
||||
;;
|
||||
atournayre-framework)
|
||||
AGENT_NAME="atournayre-framework-docs-scraper"
|
||||
;;
|
||||
claude)
|
||||
AGENT_NAME="claude-docs-scraper"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Construire paths
|
||||
if [ -n "$VERSION" ]; then
|
||||
DOCS_PATH="docs/${FRAMEWORK}/${VERSION}/"
|
||||
README_PATH="~/.claude/docs/${FRAMEWORK}/${VERSION}/README.md"
|
||||
else
|
||||
DOCS_PATH="docs/${FRAMEWORK}/"
|
||||
README_PATH="~/.claude/docs/${FRAMEWORK}/README.md"
|
||||
fi
|
||||
|
||||
echo "📁 Paths:"
|
||||
echo " - Docs: $DOCS_PATH"
|
||||
echo " - README: $README_PATH"
|
||||
echo " - Agent: @$AGENT_NAME"
|
||||
```
|
||||
|
||||
### Étape 2: Vérification README
|
||||
|
||||
```bash
|
||||
# Vérifier existence README
|
||||
if [ ! -f "$README_PATH" ]; then
|
||||
echo "❌ README introuvable: $README_PATH"
|
||||
echo "Ce fichier doit contenir la liste des URLs à charger"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Compter URLs
|
||||
TOTAL_URLS=$(grep -c "^http" "$README_PATH" || echo "0")
|
||||
if [ "$TOTAL_URLS" -eq 0 ]; then
|
||||
echo "❌ Aucune URL trouvée dans $README_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📋 URLs à traiter: $TOTAL_URLS"
|
||||
```
|
||||
|
||||
### Étape 3: Gestion Cache
|
||||
|
||||
```bash
|
||||
SKIPPED=0
|
||||
DELETED=0
|
||||
PROCESSED=0
|
||||
|
||||
# Créer répertoire si nécessaire
|
||||
mkdir -p "$DOCS_PATH"
|
||||
|
||||
# Vérifier fichiers existants
|
||||
find "$DOCS_PATH" -name "*.md" -type f | while read existing_file; do
|
||||
# Calculer âge en heures
|
||||
FILE_AGE_SECONDS=$(( $(date +%s) - $(stat -c %Y "$existing_file") ))
|
||||
FILE_AGE_HOURS=$(( FILE_AGE_SECONDS / 3600 ))
|
||||
|
||||
if [ "$FILE_AGE_HOURS" -lt "$CACHE_HOURS" ]; then
|
||||
echo "⏭️ Ignoré (récent): $existing_file ($FILE_AGE_HOURS h)"
|
||||
SKIPPED=$((SKIPPED + 1))
|
||||
else
|
||||
echo "🗑️ Supprimé (ancien): $existing_file ($FILE_AGE_HOURS h)"
|
||||
rm "$existing_file"
|
||||
DELETED=$((DELETED + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
echo "📊 Cache:"
|
||||
echo " - Fichiers ignorés (récents): $SKIPPED"
|
||||
echo " - Fichiers supprimés (anciens): $DELETED"
|
||||
```
|
||||
|
||||
### Étape 4: Chargement Documentation
|
||||
|
||||
```bash
|
||||
CREATED=0
|
||||
ERRORS=0
|
||||
|
||||
# Lire URLs depuis README
|
||||
grep "^http" "$README_PATH" | while read url; do
|
||||
# Générer nom fichier depuis URL
|
||||
FILENAME=$(echo "$url" | sed 's|https\?://||' | sed 's|[/:]|_|g' | sed 's|_$||').md
|
||||
FILEPATH="${DOCS_PATH}${FILENAME}"
|
||||
|
||||
# Vérifier si déjà traité (skipped dans cache)
|
||||
if [ -f "$FILEPATH" ]; then
|
||||
echo "⏭️ Déjà existant: $FILEPATH"
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "📥 Traitement: $url"
|
||||
|
||||
# Déléguer à agent via Task tool
|
||||
# L'agent lit l'URL, convertit en markdown, sauvegarde dans FILEPATH
|
||||
echo "Utiliser agent @$AGENT_NAME avec URL: $url"
|
||||
|
||||
# Vérifier succès
|
||||
if [ -f "$FILEPATH" ]; then
|
||||
FILE_SIZE=$(du -k "$FILEPATH" | cut -f1)
|
||||
echo "✅ Créé: $FILEPATH (${FILE_SIZE}KB)"
|
||||
CREATED=$((CREATED + 1))
|
||||
else
|
||||
echo "❌ Échec: $url"
|
||||
ERRORS=$((ERRORS + 1))
|
||||
fi
|
||||
|
||||
# Délai anti-rate-limit
|
||||
sleep 2
|
||||
done
|
||||
|
||||
PROCESSED=$((CREATED + ERRORS))
|
||||
```
|
||||
|
||||
### Étape 5: Statistiques Finales
|
||||
|
||||
```bash
|
||||
# Compter fichiers totaux
|
||||
TOTAL_FILES=$(find "$DOCS_PATH" -name "*.md" -type f | wc -l)
|
||||
|
||||
# Taille totale
|
||||
TOTAL_SIZE_KB=$(du -sk "$DOCS_PATH" | cut -f1)
|
||||
TOTAL_SIZE_MB=$(awk "BEGIN {printf \"%.2f\", $TOTAL_SIZE_KB / 1024}")
|
||||
|
||||
# Couverture
|
||||
if [ "$TOTAL_URLS" -gt 0 ]; then
|
||||
COVERAGE=$(awk "BEGIN {printf \"%.1f\", ($TOTAL_FILES / $TOTAL_URLS) * 100}")
|
||||
else
|
||||
COVERAGE="0"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "📊 Statistiques finales:"
|
||||
echo " - URLs totales: $TOTAL_URLS"
|
||||
echo " - Fichiers documentation: $TOTAL_FILES"
|
||||
echo " - Taille totale: ${TOTAL_SIZE_MB}MB"
|
||||
echo " - Couverture: ${COVERAGE}%"
|
||||
```
|
||||
|
||||
### Étape 6: Rapport Final
|
||||
|
||||
```bash
|
||||
END_TIME=$(date +%s)
|
||||
DURATION=$((END_TIME - START_TIME))
|
||||
|
||||
if [ $DURATION -lt 60 ]; then
|
||||
DURATION_STR="${DURATION}s"
|
||||
elif [ $DURATION -lt 3600 ]; then
|
||||
MINUTES=$((DURATION / 60))
|
||||
SECONDS=$((DURATION % 60))
|
||||
DURATION_STR="${MINUTES}m ${SECONDS}s"
|
||||
else
|
||||
HOURS=$((DURATION / 3600))
|
||||
MINUTES=$(((DURATION % 3600) / 60))
|
||||
SECONDS=$((DURATION % 60))
|
||||
DURATION_STR="${HOURS}h ${MINUTES}m ${SECONDS}s"
|
||||
fi
|
||||
|
||||
echo "⏱️ Durée: $DURATION_STR"
|
||||
```
|
||||
|
||||
```yaml
|
||||
task: "Chargement documentation ${FRAMEWORK}${VERSION:+ ${VERSION}}"
|
||||
status: "terminé"
|
||||
details:
|
||||
framework: "$FRAMEWORK"
|
||||
version: "${VERSION:-latest}"
|
||||
total_urls: $TOTAL_URLS
|
||||
processed: $PROCESSED
|
||||
skipped: $SKIPPED
|
||||
deleted: $DELETED
|
||||
created: $CREATED
|
||||
errors: $ERRORS
|
||||
statistics:
|
||||
documentation_files: $TOTAL_FILES
|
||||
total_size: "${TOTAL_SIZE_MB}MB"
|
||||
coverage: "${COVERAGE}%"
|
||||
notes:
|
||||
- "Documentation ${FRAMEWORK}${VERSION:+ ${VERSION}} disponible dans ${DOCS_PATH}"
|
||||
- "Fichiers individuels pour éviter conflits"
|
||||
- "Cache valide ${CACHE_HOURS}h"
|
||||
```
|
||||
|
||||
## Gestion Rate Limiting
|
||||
|
||||
**IMPORTANT** : En cas d'erreurs 429/401 :
|
||||
|
||||
1. Délai de 2-3s entre requêtes (déjà implémenté)
|
||||
2. Réduire parallélisme si nécessaire
|
||||
3. Retry avec backoff exponentiel (5s, 10s, 20s)
|
||||
4. Noter URLs en échec dans rapport final
|
||||
|
||||
## Error Handling
|
||||
|
||||
- Framework non supporté → ARRÊT (exit 1)
|
||||
- README introuvable → ARRÊT (exit 1)
|
||||
- Aucune URL dans README → ARRÊT (exit 1)
|
||||
- Échec scraping URL → WARNING + continue (non bloquant)
|
||||
|
||||
## Notes
|
||||
|
||||
- Délai 2s entre URLs pour éviter rate limiting
|
||||
- Cache 24h par défaut
|
||||
- Délègue aux agents scraper spécialisés
|
||||
- Support multi-version via argument optionnel
|
||||
- Fichiers markdown avec nommage basé sur URL
|
||||
Reference in New Issue
Block a user