Download de Slides do Changjiang Yuketang e Geração de Resumo de Revisão
Importante: Limites de Comportamento do LLM
Este Skill distingue estritamente as responsabilidades do MCP do navegador e dos scripts locais. Você deve obedecer aos seguintes limites, sendo proibido realizar operações fora deles.
O que você PODE fazer com o chrome-devtools-mcp (apenas)
- Abrir
https://changjiang.yuketang.cn/e verificar o estado de login. - Quando o usuário não estiver logado, solicitar que ele faça o login e aguardar a confirmação do usuário.
- Após o login, obter o Cookie:
- Prioritariamente, ler o campo
Cookieatravés dos cabeçalhos de solicitação do DevTools Network (é possível obter todos os Cookies, incluindo HttpOnly). - Se não for possível obter pelos cabeçalhos de solicitação, pode-se recorrer à leitura do
document.cookienão HttpOnly. - Lidar com tarefas complexas/ambíguas que os scripts não conseguem concluir (como verificação de captcha na página, pop-ups que exigem que o usuário clique manualmente na página, fluxos de login exclusivos do navegador).
- Prioritariamente, ler o campo
- Lidar com tarefas complexas/ambíguas que os scripts não conseguem concluir (como verificação de captcha na página, pop-ups que exigem que o usuário clique manualmente na página, fluxos de login exclusivos do navegador).
O que é PROIBIDO fazer com o chrome-devtools-mcp
- Chamar APIs como lista de cursos, lista de aulas, extração de PPT, etc., e ler os dados de resposta para obter informações de negócio.
- Virar páginas, capturar telas, analisar HTML da página para obter dados de cursos/aulas/PPT.
- Fazer download direto de imagens.
- Gerar ou modificar diretamente resumos de revisão.
- Usar o navegador repetidamente para testar a correção das interfaces.
Essas tarefas devem ser implementadas chamando scripts/bootstrap.js. A lista específica de interfaces está em references/yuketang-api.md.
Diferença chave: Usar MCP para ler o cabeçalho
Cookiede uma solicitação de rede é "obter estado de login" e é permitido. Usar MCP para ler o corpo de resposta de uma API é "obter dados de negócio" e é proibido.
Após construir o Manifesto Mínimo, você DEVE parar o MCP
Assim que você obtiver o Cookie via MCP, pare imediatamente todas as operações do chrome-devtools-mcp. O Cookie só pode ser passado para os scripts através da variável de ambiente RAIN_COOKIES. O arquivo de Manifesto deve conter apenas as informações do curso. As etapas subsequentes devem ser delegadas aos scripts:
set RAIN_COOKIES={"sessionid":"...","csrftoken":"...","uv_id":"0","university_id":"0","xtbz":"ykt"}
node <skill-path>/scripts/bootstrap.js verify-auth --manifest <skill-path>/tmp/manifest.jsonpara verificar o estado de login.node <skill-path>/scripts/bootstrap.js list-courses --manifest <skill-path>/tmp/manifest.json --jsonpara obter a lista de cursos.node <skill-path>/scripts/bootstrap.js --manifest <skill-path>/tmp/manifest.json --jsonpara baixar os slides (por padrão, a saída vai para o diretóriorain-class-reviewer-downloads/na raiz do projeto).node <skill-path>/scripts/bootstrap.js summarize --course-dir "rain-class-reviewer-downloads/<nome-do-curso>" --force-summarypara extrair anotações e gerar o resumo de revisão.
Para compatibilidade com a política de segurança do modo automático do Claude Code, não passe o Manifesto via stdin, nem escreva o Cookie no arquivo de Manifesto. Escreva o Manifesto final no diretório
tmp/dentro do diretório do Skill (sobrescrevendo), e faça referência a ele pelo caminho nos comandos; o Cookie é passado via variável de ambienteRAIN_COOKIES. O diretóriotmp/já está em.gitignoree não entrará no controle de versão.
Somente quando o script reportar explicitamente a necessidade de intervenção manual (como captcha, pop-ups que exigem que o usuário clique no navegador), é permitido reativar o MCP, e após o tratamento, você deve retornar imediatamente ao fluxo do script.
Visão Geral das Capacidades
- Obtenção Automática do Estado de Login: Usa chrome-devtools-mcp para conectar ao navegador, verificar/aguardar o login do usuário e extrair automaticamente o Cookie (suporta Cookie HttpOnly).
- Fluxo Scriptado: Verificação do estado de login, descoberta de cursos, listagem de aulas, download de PPT, extração de anotações em Markdown e geração de resumo de revisão são todas feitas por scripts locais.
- Download com Filtros: Suporta download por data, ID da aula, aula mais recente, etc.
- Anotações em Markdown: Cada slide do PPT é salvo como um documento Markdown independente, contendo título, pontos principais, fórmulas, palavras-chave, conceitos centrais e um resumo detalhado.
- Resumo de Revisão: Integra o conteúdo entre as páginas para gerar
review.md.
Pré-requisitos
Antes de começar a execução, você deve realizar as seguintes verificações explícitas em ordem:
-
Verificar Node.js e npm
- Execute
node -ve confirme que a versão principal é >= 18. - Execute
npm -ve confirme que o npm está disponível. - Se alguma condição não for atendida, pare e solicite ao usuário que instale Node.js >= 18.
- Execute
-
Verificar chrome-devtools-mcp
- Tente chamar uma ferramenta MCP do navegador (por exemplo,
mcp__chrome-devtools__list_pagesoumcp__chrome-devtools__navigate_page). - Se o MCP não estiver disponível, pare e solicite ao usuário que confirme se o Claude Code / OpenCode tem o chrome-devtools-mcp habilitado.
- Tente chamar uma ferramenta MCP do navegador (por exemplo,
-
Verificar a Chave de API necessária para a sumarização (apenas quando o usuário solicitar a geração do resumo de revisão)
- Verifique se a variável de ambiente
MIMO_TP_API_KEYexiste e começa comtp-. - Se já existir, continue a execução.
- Se não existir, pergunte ao usuário a Chave de API MiMo (começa com
tp-). - Após obter a chave fornecida pelo usuário, passe-a como variável de ambiente em todos os comandos subsequentes que envolvam sumarização, por exemplo:
set MIMO_TP_API_KEY=tp-xxxx node .claude/skills/rain-class-reviewer/scripts/bootstrap.js summarize --course-dir rain-class-reviewer-downloads/<nome-do-curso> - É proibido solicitar que o usuário escreva a chave em um arquivo, e também é proibido que o Skill grave a chave em disco.
- Verifique se a variável de ambiente
-
Confirmar que o usuário especificou explicitamente o nome do curso a ser baixado/sumarizado.
Início Rápido
Todos os comandos devem ser executados no diretório raiz do projeto Claude Code / OpenCode atual, chamando os scripts pelo caminho relativo até o diretório do Skill. O scripts/bootstrap.js tratará automaticamente o diretório raiz do projeto como diretório de trabalho, portanto:
- Parâmetros de caminho relativo como
--manifest,-o,--course-dir,--lesson-dirsão resolvidos em relação à raiz do projeto, sem duplicação de caminhos. - Quando
--outputnão for especificado, o diretório de download padrão será criado emrain-class-reviewer-downloads/na raiz do projeto, e não no diretório de instalação do Skill.
Na primeira chamada, o scripts/bootstrap.js usará preferencialmente o dist/cli.cjs pré-compilado (que já inclui dependências como openai), sem necessidade de instalação online; se não existir, ele executará automaticamente npm install.
Fluxo Completo
1. Pergunte ao usuário o nome do curso (ou palavras-chave).
2. Use o MCP para abrir https://changjiang.yuketang.cn/ e obter o Cookie (prioritariamente dos cabeçalhos de solicitação de rede).
3. Construa um Manifesto JSON mínimo e escreva-o em <skill-path>/tmp/manifest.json.
4. Execute node <skill-path>/scripts/bootstrap.js verify-auth --manifest <skill-path>/tmp/manifest.json para verificar o estado de login.
5. Execute node <skill-path>/scripts/bootstrap.js list-courses --manifest <skill-path>/tmp/manifest.json --json para obter a lista de cursos.
6. Corresponda o curso com base na entrada do usuário; em caso de ambiguidade, mostre as opções ao usuário e confirme o classroomId.
7. Use o courseName original retornado pela lista de cursos para construir um Manifesto com classroomId (sobrescrevendo tmp/manifest.json) e execute node <skill-path>/scripts/bootstrap.js --manifest <skill-path>/tmp/manifest.json --json para baixar (a saída padrão vai para rain-class-reviewer-downloads/).
8. Defina `MIMO_TP_API_KEY` e execute `node <skill-path>/scripts/bootstrap.js summarize --course-dir "rain-class-reviewer-downloads/<nome-do-curso original>" --force-summary` para gerar o resumo de revisão.
Exemplo (caminho do Skill no projeto 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
Fluxo de Execução Padrão
1. Obter o nome do curso desejado pelo usuário
Pergunte ao usuário o nome do curso, permitindo abreviações ou palavras-chave, por exemplo, "Redes de Computadores". Registre a entrada original do usuário, não faça nenhuma correspondência imediatamente.
2. Usar MCP para obter o Cookie
O sessionid do Changjiang Yuketang é geralmente um Cookie HttpOnly, que não pode ser lido via document.cookie. Você deve obtê-lo através dos cabeçalhos de solicitação de rede do Chrome DevTools, e deve usar estritamente as URLs listadas abaixo.
2.1 Abrir a página do Changjiang Yuketang
URL que deve ser navegada:
https://changjiang.yuketang.cn/
Passos:
- Conecte-se ao navegador.
- Use
mcp__chrome-devtools__navigate_pagepara navegar até:https://changjiang.yuketang.cn/ - Se a página já tiver sido carregada, use
type=reloadpara recarregar a mesma URL, a fim de gerar novas solicitações de rede:mcp__chrome-devtools__navigate_page: type=reload, url=https://changjiang.yuketang.cn/
2.2 Disparar uma solicitação de rede com Cookie
Após recarregar a página, o navegador normalmente gera várias solicitações com Cookie automaticamente. Se não houver solicitações suficientes, você deve ativamente disparar a seguinte URL:
URL de disparo preferencial (esta URL é idêntica à interface de listagem de cursos usada pelos scripts verify-auth / list-courses posteriormente, sendo segura e reutilizável):
GET https://changjiang.yuketang.cn/v2/api/web/courses/list?identity=2
Forma de disparo (escolha uma, apenas para gerar tráfego de solicitação, é proibido ler dados de negócio da resposta):
- Opção A: Execute um refresh da página (veja 2.1).
- Opção B: Execute via
evaluate_script:fetch('https://changjiang.yuketang.cn/v2/api/web/courses/list?identity=2', { credentials: 'include' });
URL de disparo alternativa (quando a solicitação preferencial não aparecer, qualquer solicitação para changjiang.yuketang.cn é aceitável):
https://changjiang.yuketang.cn/ (documento da página)
https://changjiang.yuketang.cn/v2/web/index (página inicial)
https://changjiang.yuketang.cn/* (recursos estáticos sob o mesmo domínio, como JS/CSS)
É proibido usar outros subdomínios do Yuketang ou interfaces de terceiros para detectar o Cookie.
2.3 Ler o Cookie dos cabeçalhos de solicitação de rede
- Chame
list_network_requestspara visualizar as solicitações recentes. - Na lista de solicitações, selecione uma com a seguinte prioridade:
- Prioritário:
https://changjiang.yuketang.cn/v2/api/web/courses/list?identity=2 - Segunda opção:
https://changjiang.yuketang.cn/ouhttps://changjiang.yuketang.cn/v2/web/index - Aceitável: Qualquer solicitação
https://changjiang.yuketang.cn/*
- Prioritário:
- Use
get_network_requestpara ler os Cabeçalhos da Solicitação (Request Headers). - Encontre o campo
cookieouCookienos cabeçalhos e analise os seguintes campos:sessionid(obrigatório)csrftoken(recomendado, usado para validação CSRF)uv_id(extrair com base no valor real, pode ser0ou outro valor)university_id(extrair com base no valor real, pode ser igual ou diferente deuv_id)xtbz(geralmenteykt)django_language(opcional)
Exemplo de cabeçalho Cookie:
sessionid=abc123; csrftoken=xyz789; uv_id=0; university_id=0; xtbz=ykt
Não codifique
uv_id=2874ouuniversity_id=2874diretamente; você deve ler os valores reais dos cabeçalhos da solicitação. Valores ausentes ou0são permitidos.
2.4 Lidar com o caso de não estar logado
- Se o cabeçalho da solicitação não contiver
sessionid, ou se a solicitação for redirecionada para a página de login, significa que o usuário não está logado. - Solicite ao usuário que faça login manualmente no Changjiang Yuketang.
- Aguarde o usuário responder "logado".
- Recarregue a página ou dispare novamente
https://changjiang.yuketang.cn/v2/api/web/courses/list?identity=2e releia o Cookie.
2.5 Plano de contingência
Se o MCP não conseguir fornecer o Cookie dos cabeçalhos:
- Tente ler o
document.cookiepara obter Cookies não HttpOnly (geralmente pelo menos ocsrftokené obtido). - Se ainda assim não conseguir obter o
sessionid, peça ao usuário que forneça osessionidmanualmente, ou verifique se o MCP suporta a obtenção de Cookies HttpOnly. - Independentemente do sucesso do plano de contingência, você ainda deve, no final, obter o
sessionidatravés dos cabeçalhos de solicitação de rede.
3. Construir o Manifesto Mínimo
{
"version": "1.0",
"courseName": "Redes de Computadores"
}
courseName usa a entrada original do usuário. Este Manifesto é usado apenas para verificação e obtenção da lista de cursos, não garantindo a correspondência final. Após construir este Manifesto, pare o MCP imediatamente.
O Cookie é passado através da variável de ambiente RAIN_COOKIES (o mesmo se aplica abaixo):
set RAIN_COOKIES={"sessionid":"...","csrftoken":"...","uv_id":"0","university_id":"0","xtbz":"ykt"}
4. Verificar o estado de login
set RAIN_COOKIES={...}
node <caminho-do-skill>/scripts/bootstrap.js verify-auth --manifest <caminho-do-skill>/tmp/manifest.json
- Sucesso: continue para a próxima etapa.
- Falha: retorne à etapa 2 e obtenha o Cookie novamente.
5. Obter a lista de cursos
set RAIN_COOKIES={...}
node <caminho-do-skill>/scripts/bootstrap.js list-courses --manifest <caminho-do-skill>/tmp/manifest.json --json
Retorna classroomId, courseName, className, teacher de todos os cursos da conta atual.
6. Corresponder o curso e lidar com ambiguidades
Use a entrada original do usuário para corresponder à lista de cursos:
- Correspondência única e exata: Use esse
classroomIddiretamente. - Nenhuma correspondência: Mostre todos os cursos disponíveis ao usuário e peça que ele especifique o nome do curso ou
classroomId. - Múltiplas correspondências: Mostre os cursos candidatos ao usuário (incluindo turma, professor, classroomId) e peça confirmação.
É proibido escolher por conta própria. Após a confirmação, use o courseName original retornado pela lista de cursos para construir um novo Manifesto e sobrescreva tmp/manifest.json:
{
"version": "1.0",
"courseName": "Redes de Computadores",
"classroomId": "13522533"
}
7. Baixar os slides
set RAIN_COOKIES={...}
node <caminho-do-skill>/scripts/bootstrap.js --manifest <caminho-do-skill>/tmp/manifest.json --json
8. Extrair anotações em Markdown e gerar o resumo de revisão
set MIMO_TP_API_KEY=tp-xxxx
node <caminho-do-skill>/scripts/bootstrap.js summarize --course-dir "rain-class-reviewer-downloads/<nome-do-curso>" --force-summary
Saída:
- Anotações Markdown por slide:
rain-class-reviewer-downloads/<nome-do-curso>/extracted/<aula>/<pagina>.md - Resumo de revisão geral:
rain-class-reviewer-downloads/<nome-do-curso>/review.md
Download Filtrado por Aula
Baixar apenas a aula mais recente:
node <caminho-do-skill>/scripts/bootstrap.js --manifest <caminho-do-skill>/tmp/manifest.json --latest --json
Baixar por intervalo de datas:
node <caminho-do-skill>/scripts/bootstrap.js --manifest <caminho-do-skill>/tmp/manifest.json --since 2023-11-01 --until 2023-11-05 --json
Tratamento de Ambiguidade no Nome do Curso
- Se houver vários cursos com o mesmo nome, o script reportará um erro e listará os
classroomIdcandidatos. - É proibido escolher por conta própria, você deve mostrar os cursos candidatos ao usuário e solicitar confirmação.
- Após a confirmação, especifique
classroomIdexplicitamente no Manifesto antes de chamar o script.
Tratamento de Falha de Autenticação
Se o script retornar 403 / não logado / falha na verificação de autenticação:
- Explique que o
sessionidexpirou ou está ausente. - Reexecute a etapa 2 (usar MCP para verificar/refazer o login).
- Atualize a variável de ambiente
RAIN_COOKIES. - Reexecute o script.
Notas Especiais para o Modo Automático do Claude Code
O arquivo de Manifesto deste Skill não contém mais credenciais como Cookies; o Cookie só pode ser passado através da variável de ambiente RAIN_COOKIES. Portanto, Write(tmp/manifest.json) escreve apenas o nome do curso/classroomId, geralmente passando pela verificação de gravação de arquivos do modo automático.
Se o modo automático ainda assim bloquear a gravação do arquivo temporário, crie manualmente .claude/policy.json na raiz do projeto atual:
{
"autoMode": {
"allow": [
"Permitir a gravação do arquivo de manifesto do skill rain-class-reviewer em .claude/skills/rain-class-reviewer/tmp/manifest.json, que contém apenas o nome do curso e classroomId.",
"Permitir a execução de comandos node .claude/skills/rain-class-reviewer/scripts/bootstrap.js para download e sumarização de cursos."
]
}
}
Todos os comandos devem incluir a variável de ambiente 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
No Git Bash / Linux / macOS, use
export RAIN_COOKIES='...'.
Segurança e Privacidade
- É proibido exibir o Cookie completo em texto puro na conversa.
- O Manifesto é gravado em
tmp/manifest.jsondentro do diretório do Skill, sobrescrevendo o conteúdo anterior; o Manifesto não deve conter o campo cookies. O diretóriotmp/já está em.gitignoree não entrará no controle de versão. - O Cookie só pode ser passado através da variável de ambiente
RAIN_COOKIES. Não salvecookies.jsonseparadamente. - O diretório de download
rain-class-reviewer-downloads/e o diretório temporáriotmp/já estão em.gitignore.
Limitações Conhecidas
- A ferramenta usa preferencialmente as novas interfaces
lesson-summary+presentationpara obter o PPT completo; se não estiver disponível, ela recai automaticamente para a interfacereview, mas esta última contém apenas os slides exibidos durante a aula. - A funcionalidade de sumarização depende da Chave de API MiMo, que deve ser passada através da variável de ambiente
MIMO_TP_API_KEY. É proibido gravá-la em um arquivo.
Referências
references/yuketang-api.md: Lista e restrições das interfaces do Changjiang Yuketang.references/manifest.example.json: Exemplo completo de Manifesto.docs/usage.md: Documentação completa dos parâmetros da CLI.docs/implementation.md: Detalhes de implementação.