Téléchargement des diapositives de Changjiang Yuketang et génération de plans de révision
Important : Limites de comportement de l'IA
Ce Skill distingue strictement les responsabilités du MCP navigateur et du script local. Vous devez respecter ces limites, toute opération hors limite est interdite.
Ce que vous pouvez faire avec chrome-devtools-mcp (uniquement)
- Ouvrir
https://changjiang.yuketang.cn/et vérifier l'état de connexion. - Si l'utilisateur n'est pas connecté, lui demander de se connecter et attendre sa confirmation.
- Après connexion, récupérer le cookie :
- En priorité, lire le champ
Cookiedans les en-têtes de requête réseau DevTools (permet d'obtenir tous les cookies, y compris HttpOnly). - Si impossible, utiliser
document.cookiepour les cookies non HttpOnly.
- En priorité, lire le champ
- Gérer les tâches complexes/floues que le script ne peut pas accomplir (vérification humaine, fenêtres modales nécessitant une sélection manuelle, processus de connexion propre au navigateur).
Ce qui est interdit avec chrome-devtools-mcp
- Appeler des API de liste de cours, de liste de leçons, d'extraction de PPT et lire les données de réponse pour obtenir des informations métier.
- Paginer, capturer des écrans, analyser le HTML pour obtenir des données de cours/leçon/PPT.
- Télécharger directement des images.
- Générer ou modifier directement des plans de révision.
- Tester de manière répétée les points d'accès avec le navigateur.
Ces tâches doivent être réalisées en appelant scripts/bootstrap.js. La liste des interfaces est dans references/yuketang-api.md.
Différence clé : Lire l'en-tête
Cookiedes requêtes réseau avec MCP est une "obtention de l'état de connexion", autorisée. Lire le corps des réponses API avec MCP est une "obtention de données métier", interdite.
Arrêter le MCP après avoir construit le manifeste minimal
Une fois que vous avez obtenu le cookie via MCP, arrêtez immédiatement toute opération chrome-devtools-mcp. Le cookie ne peut être transmis aux scripts que via la variable d'environnement RAIN_COOKIES ; le fichier manifeste ne contient que les informations du cours. Les étapes suivantes doivent être confiées au script :
set RAIN_COOKIES={"sessionid":"...","csrftoken":"...","uv_id":"0","university_id":"0","xtbz":"ykt"}
node <chemin-du-skill>/scripts/bootstrap.js verify-auth --manifest <chemin-du-skill>/tmp/manifest.jsonpour vérifier l'état de connexion.node <chemin-du-skill>/scripts/bootstrap.js list-courses --manifest <chemin-du-skill>/tmp/manifest.json --jsonpour obtenir la liste des cours.node <chemin-du-skill>/scripts/bootstrap.js --manifest <chemin-du-skill>/tmp/manifest.json --jsonpour télécharger les diapositives (par défaut dans le répertoirerain-class-reviewer-downloads/à la racine du projet).node <chemin-du-skill>/scripts/bootstrap.js summarize --course-dir "rain-class-reviewer-downloads/<nom du cours>" --force-summarypour extraire les notes et générer un plan de révision.
Pour respecter les politiques de sécurité du mode automatique de Claude Code, ne transmettez pas le manifeste via stdin et n'écrivez pas le cookie dans le fichier manifeste. Écrivez le manifeste final dans
tmp/manifest.json(en écrasant) et référencez-le par son chemin ; transmettez le cookie viaRAIN_COOKIES. Le répertoiretmp/est inclus dans.gitignore, il n'entre pas dans le contrôle de version.
Ne réactivez le MCP que si le script signale explicitement un besoin d'intervention humaine (captcha, sélection manuelle dans le navigateur), et revenez immédiatement au script après traitement.
Aperçu des capacités
- Obtention automatique de l'état de connexion : Utilise chrome-devtools-mcp pour se connecter au navigateur, vérifier/attendre la connexion et extraire automatiquement le cookie (y compris HttpOnly).
- Traitement scripté des étapes suivantes : Vérification de l'état de connexion, découverte des cours, liste des leçons, téléchargement PPT, extraction de notes Markdown et génération de plans de révision, le tout via des scripts locaux.
- Téléchargement filtré : Prise en charge du filtrage par date, ID de leçon, dernière leçon, etc.
- Notes Markdown : Chaque diapositive PPT est sauvegardée en un document Markdown indépendant, incluant titre, points clés, formules, mots-clés, concepts centraux et résumé détaillé.
- Plan de révision : Intégration entre les pages pour générer
review.md.
Prérequis
Avant de commencer, effectuez les vérifications explicites suivantes dans l'ordre :
-
Vérifier Node.js et npm
- Exécutez
node -vpour confirmer que la version majeure >= 18. - Exécutez
npm -vpour confirmer que npm est disponible. - Si l'une des conditions n'est pas remplie, arrêtez et demandez à l'utilisateur d'installer Node.js >= 18.
- Exécutez
-
Vérifier chrome-devtools-mcp
- Essayez d'appeler un outil MCP navigateur (par exemple
mcp__chrome-devtools__list_pagesoumcp__chrome-devtools__navigate_page). - Si MCP n'est pas disponible, arrêtez et demandez à l'utilisateur de confirmer que Claude Code / OpenCode a activé chrome-devtools-mcp.
- Essayez d'appeler un outil MCP navigateur (par exemple
-
Vérifier la clé API nécessaire pour le résumé (uniquement si l'utilisateur demande la génération d'un plan de révision)
- Vérifiez si la variable d'environnement
MIMO_TP_API_KEYexiste et commence partp-. - Si elle existe, continuez.
- Si elle n'existe pas, demandez à l'utilisateur la clé API MiMo (commençant par
tp-). - Une fois la clé fournie, transmettez-la dans toutes les commandes de résumé via la variable d'environnement, par exemple :
set MIMO_TP_API_KEY=tp-xxxx node .claude/skills/rain-class-reviewer/scripts/bootstrap.js summarize --course-dir rain-class-reviewer-downloads/<nom du cours> - Interdiction de demander à l'utilisateur d'écrire la clé dans un fichier, et interdiction pour le Skill de la stocker sur le disque.
- Vérifiez si la variable d'environnement
-
Confirmer que l'utilisateur a explicitement spécifié le nom du cours à télécharger/résumer.
Démarrage rapide
Toutes les commandes doivent être exécutées depuis le répertoire racine du projet Claude Code / OpenCode en utilisant le chemin relatif vers le répertoire du Skill pour appeler les scripts. scripts/bootstrap.js considère automatiquement la racine du projet comme répertoire de travail, donc :
- Les chemins relatifs pour
--manifest,-o,--course-dir,--lesson-dirsont résolus par rapport à la racine du projet, sans duplication de chemin. - Sans spécifier
--output, le répertoire de téléchargement par défaut est créé dansrain-class-reviewer-downloads/à la racine du projet, et non dans le répertoire d'installation du Skill.
Lors du premier appel, scripts/bootstrap.js utilise prioritairement le fichier dist/cli.cjs pré-construit (qui inclut les dépendances comme openai), sans nécessiter d'installation en ligne ; s'il n'existe pas, il exécute automatiquement npm install.
Processus complet
1. Demander à l'utilisateur le nom du cours (ou un mot-clé).
2. Ouvrir https://changjiang.yuketang.cn/ avec MCP et récupérer le cookie (en priorité depuis les en-têtes de requête réseau).
3. Construire un manifeste JSON minimal, l'écrire dans <chemin-du-skill>/tmp/manifest.json.
4. Exécuter node <chemin-du-skill>/scripts/bootstrap.js verify-auth --manifest <chemin-du-skill>/tmp/manifest.json pour vérifier l'état de connexion.
5. Exécuter node <chemin-du-skill>/scripts/bootstrap.js list-courses --manifest <chemin-du-skill>/tmp/manifest.json --json pour obtenir la liste des cours.
6. Faire correspondre le cours avec la saisie utilisateur ; en cas d'ambiguïté, présenter les candidats à l'utilisateur et confirmer le classroomId.
7. Utiliser le courseName original de la liste, construire un manifeste avec classroomId (écraser tmp/manifest.json), exécuter node <chemin-du-skill>/scripts/bootstrap.js --manifest <chemin-du-skill>/tmp/manifest.json --json pour télécharger (par défaut dans rain-class-reviewer-downloads/).
8. Définir `MIMO_TP_API_KEY`, puis exécuter `node <chemin-du-skill>/scripts/bootstrap.js summarize --course-dir "rain-class-reviewer-downloads/<nom du cours original>" --force-summary` pour générer le plan de révision.
Exemple (chemin de Skill au niveau projet Claude Code : .claude/skills/rain-class-reviewer) :
node .claude/skills/rain-class-reviewer/scripts/bootstrap.js \
--manifest .claude/skills/rain-class-reviewer/tmp/manifest.json --json
Processus d'exécution standard
1. Obtenir le nom du cours souhaité par l'utilisateur
Confirmez le nom du cours avec l'utilisateur, en acceptant les abréviations ou mots-clés, par exemple "Réseaux informatiques". Enregistrez la saisie originale de l'utilisateur sans effectuer de correspondance immédiate.
2. Utiliser MCP pour obtenir le cookie
Le sessionid de Changjiang Yuketang est généralement un cookie HttpOnly et ne peut pas être lu via document.cookie. Vous devez l'obtenir via les en-têtes de requête réseau de Chrome DevTools, et strictement en utilisant les URL listées ci-dessous.
2.1 Ouvrir la page Changjiang Yuketang
URL obligatoire :
https://changjiang.yuketang.cn/
Étapes :
- Se connecter au navigateur.
- Utiliser
mcp__chrome-devtools__navigate_pagepour naviguer vers :https://changjiang.yuketang.cn/ - Si la page est déjà chargée, utiliser
type=reloadpour rafraîchir la même URL, afin de générer de nouvelles requêtes réseau :mcp__chrome-devtools__navigate_page: type=reload, url=https://changjiang.yuketang.cn/
2.2 Déclencher une requête réseau avec cookie
Après le rafraîchissement, le navigateur génère généralement plusieurs requêtes avec cookie. Si vous n'en voyez pas assez, déclenchez activement l'URL suivante :
URL de déclenchement privilégiée (cette URL est identique à l'interface de liste de cours utilisée par le script pour verify-auth / list-courses, sûre et réutilisable) :
GET https://changjiang.yuketang.cn/v2/api/web/courses/list?identity=2
Mode de déclenchement (au choix, uniquement pour générer du trafic, interdiction de lire les données métier de la réponse) :
- Option A : Effectuer un rafraîchissement de page (voir 2.1).
- Option B : Exécuter via
evaluate_script:fetch('https://changjiang.yuketang.cn/v2/api/web/courses/list?identity=2', { credentials: 'include' });
URL de déclenchement secondaire (si la requête privilégiée n'apparaît pas, toute requête vers changjiang.yuketang.cn est acceptable) :
https://changjiang.yuketang.cn/ (document de la page)
https://changjiang.yuketang.cn/v2/web/index (page d'accueil)
https://changjiang.yuketang.cn/* (ressources statiques sous le même domaine, JS/CSS)
Interdiction d'utiliser d'autres sous-domaines de Yuketang ou des API tierces pour détecter le cookie.
2.3 Lire le cookie depuis les en-têtes de requête réseau
- Appeler
list_network_requestspour voir les requêtes récentes. - Dans la liste, sélectionner une requête par ordre de priorité :
- Priorité :
https://changjiang.yuketang.cn/v2/api/web/courses/list?identity=2 - Secondaire :
https://changjiang.yuketang.cn/ouhttps://changjiang.yuketang.cn/v2/web/index - Acceptable : Toute requête
https://changjiang.yuketang.cn/*
- Priorité :
- Utiliser
get_network_requestpour lire les en-têtes de requête. - Trouver le champ
cookieouCookieet extraire les champs suivants :sessionid(obligatoire)csrftoken(recommandé, pour la validation CSRF)uv_id(selon la valeur réelle, peut être0ou autre)university_id(selon la valeur réelle, peut être identique ou différent deuv_id)xtbz(généralementykt)django_language(optionnel)
Exemple d'en-tête Cookie :
sessionid=abc123; csrftoken=xyz789; uv_id=0; university_id=0; xtbz=ykt
Ne coderez pas en dur
uv_id=2874ouuniversity_id=2874, lisez les valeurs réelles dans l'en-tête de requête. Des valeurs manquantes ou0sont acceptables.
2.4 Gérer le cas où l'utilisateur n'est pas connecté
- Si l'en-tête de requête ne contient pas
sessionid, ou si la requête est redirigée vers la page de connexion, cela signifie que l'utilisateur n'est pas connecté. - Demandez à l'utilisateur de se connecter manuellement à Changjiang Yuketang.
- Attendez que l'utilisateur réponde "connecté".
- Rafraîchissez la page ou déclenchez à nouveau
https://changjiang.yuketang.cn/v2/api/web/courses/list?identity=2, puis relisez le cookie.
2.5 Solution de repli
Si MCP ne peut pas fournir le cookie dans les en-têtes de requête :
- Essayez de lire
document.cookiepour obtenir les cookies non HttpOnly (généralement au moinscsrftoken). - Si vous ne pouvez toujours pas obtenir
sessionid, demandez à l'utilisateur de fournir manuellementsessionid, ou vérifiez si MCP prend en charge l'obtention de cookies HttpOnly. - Que le repli réussisse ou non, vous devez finalement obtenir
sessionidvia les en-têtes de requête réseau.
3. Construire le manifeste minimal
{
"version": "1.0",
"courseName": "Réseaux informatiques"
}
courseName utilise la saisie originale de l'utilisateur. Ce manifeste sert uniquement à la vérification et à l'obtention de la liste des cours, sans garantie de correspondance finale. Après avoir construit ce manifeste, arrêtez immédiatement le MCP.
Le cookie est transmis via la variable d'environnement RAIN_COOKIES (idem ci-dessous) :
set RAIN_COOKIES={"sessionid":"...","csrftoken":"...","uv_id":"0","university_id":"0","xtbz":"ykt"}
4. Vérifier l'état de connexion
set RAIN_COOKIES={...}
node <chemin-du-skill>/scripts/bootstrap.js verify-auth --manifest <chemin-du-skill>/tmp/manifest.json
- Succès : passer à l'étape suivante.
- Échec : revenir à l'étape 2, réobtenir le cookie.
5. Obtenir la liste des cours
set RAIN_COOKIES={...}
node <chemin-du-skill>/scripts/bootstrap.js list-courses --manifest <chemin-du-skill>/tmp/manifest.json --json
Retourne classroomId, courseName, className, teacher pour tous les cours du compte.
6. Faire correspondre le cours et gérer les ambiguïtés
Faire correspondre la saisie originale de l'utilisateur avec la liste des cours :
- Correspondance unique et exacte : utiliser directement ce
classroomId. - Aucune correspondance : montrer tous les cours disponibles à l'utilisateur et lui demander de spécifier le nom du cours ou le
classroomId. - Plusieurs correspondances : montrer les cours candidats (avec classe, enseignant, classroomId) et demander confirmation à l'utilisateur.
Interdiction d'agir de votre propre chef. Après confirmation, utilisez le courseName original de la liste pour construire un nouveau manifeste et écraser tmp/manifest.json :
{
"version": "1.0",
"courseName": "Réseaux informatiques",
"classroomId": "13522533"
}
7. Télécharger les diapositives
set RAIN_COOKIES={...}
node <chemin-du-skill>/scripts/bootstrap.js --manifest <chemin-du-skill>/tmp/manifest.json --json
8. Extraire les notes Markdown et générer le plan de révision
set MIMO_TP_API_KEY=tp-xxxx
node <chemin-du-skill>/scripts/bootstrap.js summarize --course-dir "rain-class-reviewer-downloads/<nom du cours>" --force-summary
Sortie :
- Notes Markdown par page :
rain-class-reviewer-downloads/<nom du cours>/extracted/<leçon>/<page>.md - Plan de révision global :
rain-class-reviewer-downloads/<nom du cours>/review.md
Téléchargement filtré par leçon
Télécharger uniquement la dernière leçon :
node <chemin-du-skill>/scripts/bootstrap.js --manifest <chemin-du-skill>/tmp/manifest.json --latest --json
Télécharger par plage de dates :
node <chemin-du-skill>/scripts/bootstrap.js --manifest <chemin-du-skill>/tmp/manifest.json --since 2023-11-01 --until 2023-11-05 --json
Gestion des ambiguïtés de nom de cours
- Si plusieurs cours portent le même nom, le script signalera une erreur et listera les
classroomIdcandidats. - Interdiction d'agir de votre propre chef, vous devez montrer les cours candidats à l'utilisateur et demander confirmation.
- Après confirmation, spécifiez explicitement
classroomIddans le manifeste avant d'appeler le script.
Gestion des échecs d'authentification
Si le script retourne 403 / "non connecté" / échec de validation :
- Expliquez que
sessionida expiré ou est manquant. - Reprenez l'étape 2 (vérification/reconnexion avec MCP).
- Mettez à jour la variable d'environnement
RAIN_COOKIES. - Relancez le script.
Note spéciale pour le mode automatique de Claude Code
Le fichier manifeste de ce Skill ne contient plus de cookies ou d'identifiants ; le cookie ne peut être transmis que via la variable d'environnement RAIN_COOKIES. Par conséquent, Write(tmp/manifest.json) n'écrit que le nom du cours/classroomId, ce qui passe généralement les vérifications d'écriture du mode automatique.
Si le mode automatique bloque encore l'écriture de fichiers temporaires, créez manuellement .claude/policy.json à la racine du projet :
{
"autoMode": {
"allow": [
"Allow writing the rain-class-reviewer skill manifest file at .claude/skills/rain-class-reviewer/tmp/manifest.json, which only contains course name and classroomId.",
"Allow running node .claude/skills/rain-class-reviewer/scripts/bootstrap.js commands for course download and summarization."
]
}
}
Toutes les commandes doivent inclure la variable d'environnement RAIN_COOKIES :
set RAIN_COOKIES={"sessionid":"...","csrftoken":"...","uv_id":"0","university_id":"0","xtbz":"ykt"}
node .claude/skills/rain-class-reviewer/scripts/bootstrap.js verify-auth --manifest .claude/skills/rain-class-reviewer/tmp/manifest.json
Sous Git Bash / Linux / macOS, utilisez
export RAIN_COOKIES='...'.
Sécurité et confidentialité
- Interdiction d'afficher le cookie complet en clair dans la conversation.
- Le manifeste est écrit dans
tmp/manifest.jsondans le répertoire du Skill, en écrasant le contenu précédent ; le manifeste ne doit pas contenir de champ cookies.tmp/est inclus dans.gitignore, il n'entre pas dans le contrôle de version. - Le cookie ne peut être transmis que via la variable d'environnement
RAIN_COOKIES, ne sauvegardez pas decookies.jsonséparément. - Le répertoire de téléchargement
rain-class-reviewer-downloads/et le répertoire temporairetmp/sont inclus dans.gitignore.
Limitations connues
- L'outil utilise prioritairement les nouvelles interfaces
lesson-summary+presentationpour obtenir les PPT complets ; si indisponible, il se replie automatiquement sur l'interfacereview, qui ne contient que les diapositives affichées en classe. - La fonction de résumé dépend de la clé API MiMo, qui doit être transmise via la variable d'environnement
MIMO_TP_API_KEY; interdiction de l'écrire dans un fichier.
Références
references/yuketang-api.md: Liste des interfaces de Changjiang Yuketang et contraintes.references/manifest.example.json: Exemple complet de manifeste.docs/usage.md: Documentation complète des paramètres CLI.docs/implementation.md: Détails d'implémentation.