Community研究&データ分析github.com

DonAzufre/rain-class-reviewer

长江雨课堂のコーススライドをダウンロードし、CLIおよびインストール可能なエージェントスキルとして構造化された復習資料を生成します。

rain-class-reviewer とは?

このスキルは、长江雨课堂(Changjiang Yuketang)のコーススライドをダウンロードし、Markdownノートと復習概要を自動生成するためのツールです。主にClaude CodeやOpenCodeなどのAIエージェント環境で動作し、chrome-devtools-mcpを用いてブラウザのCookieを安全に取得した後、ローカルスクリプト(scripts/bootstrap.js)で認証確認、コース一覧取得、PPTダウンロード、ノート抽出、復習概要生成を全て実行します。ブラウザMCPはCookie取得のみに使用し、それ以外の業務データ取得やファイル生成は一切行わないという明確な責任分担が特徴です。日付や授業IDによるフィルタリングダウンロード、最新授業のみのダウンロード、同名コースの曖昧性解消など、柔軟なダウンロードオプションを提供します。また、生成された復習概要は、各ページごとのMarkdownノートとコース全体のreview.mdとして出力され、MiMo API(MIMO_TP_API_KEY)を利用してAIによる高品質な要約を実現します。このスキルは、长江雨课堂ユーザーがオフラインでコース内容を効率的に復習したい場合に非常に有用です。

対応✓Claude Code✓Codex CLI~Cursor✓OpenCode
npx skills add DonAzufre/rain-class-reviewer

Installed? Explore more 研究&データ分析 skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

长江雨课堂 コーススライドダウンロード&復習概要生成

重要:LLMの行動境界

本スキルは、ブラウザMCPとローカルスクリプトの役割を厳密に区別します。以下の境界を遵守し、越権操作を禁止します。

chrome-devtools-mcpで許可されること(限定)

  1. https://changjiang.yuketang.cn/ を開き、ログイン状態を確認する。
  2. ユーザーが未ログインの場合、ログインを促し、ユーザーの確認を待つ。
  3. ログイン後にCookieを取得する:
    • 優先:DevTools Networkリクエストヘッダーから Cookie フィールドを読み取る(HttpOnlyを含む全てのCookieを取得可能)。
    • リクエストヘッダーで取得できない場合、非HttpOnlyの document.cookie を読み取るフォールバックを使用する。
    • スクリプトでは完了できない複雑/曖昧なタスクを処理する(例:ページのCAPTCHA、ユーザーが手動でクリックする必要があるポップアップ、ブラウザ独自のログインフロー)。
  4. スクリプトでは完了できない複雑/曖昧なタスクを処理する(例:ページのCAPTCHA、ユーザーが手動でクリックする必要があるポップアップ、ブラウザ独自のログインフロー)。

chrome-devtools-mcpで禁止されること

  • コース一覧、授業一覧、PPT抽出などのAPIを呼び出し、レスポンスデータをビジネス情報として読み取ること。
  • ページング、スクリーンショット、ページHTMLの解析を行い、コース/授業/PPTデータを取得すること。
  • 画像を直接ダウンロードすること。
  • 復習概要を直接生成または変更すること。
  • ブラウザを使ってAPIの正しさを繰り返しプローブすること。

これらのタスクは scripts/bootstrap.js を使用して実装する必要があります。 具体的なAPI一覧は references/yuketang-api.md を参照してください。

重要な違い:MCPでネットワークリクエストの Cookie ヘッダーを読み取ることは「ログイン状態の取得」であり許可されますが、MCPでAPIレスポンスボディを読み取ることは「ビジネスデータの取得」であり禁止されます。

最小Manifest構築後はMCPを停止すること

MCPでCookieを取得したら、直ちに全てのchrome-devtools-mcp操作を停止します。Cookieは RAIN_COOKIES 環境変数でのみスクリプトに渡され、Manifestファイルにはコース情報のみが保持されます。以降のステップはスクリプトに委ねます:

set RAIN_COOKIES={"sessionid":"...","csrftoken":"...","uv_id":"0","university_id":"0","xtbz":"ykt"}
  1. node <skill-path>/scripts/bootstrap.js verify-auth --manifest <skill-path>/tmp/manifest.json でログイン状態を検証。
  2. node <skill-path>/scripts/bootstrap.js list-courses --manifest <skill-path>/tmp/manifest.json --json でコース一覧を取得。
  3. node <skill-path>/scripts/bootstrap.js --manifest <skill-path>/tmp/manifest.json --json でスライドをダウンロード(デフォルト出力先はプロジェクトルートの rain-class-reviewer-downloads/)。
  4. node <skill-path>/scripts/bootstrap.js summarize --course-dir "rain-class-reviewer-downloads/<コース名>" --force-summary でノートを抽出し復習概要を生成。

Claude Codeのauto modeのセキュリティポリシーと互換性を保つため、Manifestをstdinで渡さず、ManifestファイルにCookieを書き込まないでください。最終的なManifestはスキルディレクトリ内の tmp/manifest.json に(上書きで)書き込み、コマンド内でパス参照してください。Cookieは RAIN_COOKIES 環境変数で渡します。tmp/ は .gitignore に含まれているため、バージョン管理には入りません。

スクリプトが明示的に手動処理(CAPTCHA、ユーザーがブラウザで選択する必要がある場合など)を必要とする場合のみ、再度MCPの使用を許可します。処理後はすぐにスクリプトフローに戻る必要があります。

機能概要

  • 自動ログイン状態取得:chrome-devtools-mcpを使用してブラウザに接続し、ユーザーログインを確認/待機した後、自動的にCookieを抽出(HttpOnly Cookieもサポート)。
  • スクリプト化された後続処理:ログイン状態検証、コース発見、授業一覧、PPTダウンロード、Markdownノート抽出、復習概要生成を全てローカルスクリプトで実行。
  • フィルタリングダウンロード:日付、授業ID、最新授業などによる条件指定ダウンロードをサポート。
  • Markdownノート:PPTの各ページを個別のMarkdownドキュメントとして保存。タイトル、要点、数式、キーワード、コア概念、詳細な要約を含む。
  • 復習概要:ページをまたいで統合し、review.md を生成。

前提条件

実行を開始する前に、以下の明示的なチェックを順に実行する必要があります:

  1. Node.jsとnpmの確認

    • node -v を実行し、メジャーバージョンが18以上であることを確認。
    • npm -v を実行し、npmが利用可能であることを確認。
    • いずれかが満たされない場合、停止し、Node.js 18以上をインストールするようユーザーに促す。
  2. chrome-devtools-mcpの確認

    • MCPブラウザツール(例:mcp__chrome-devtools__list_pages または mcp__chrome-devtools__navigate_page)を一度呼び出してみる。
    • MCPが利用できない場合、停止し、ユーザーにClaude Code / OpenCodeでchrome-devtools-mcpが有効になっていることを確認するよう促す。
  3. 要約に必要なAPI Keyの確認(ユーザーが復習概要の生成を要求した場合のみ)

    • 環境変数 MIMO_TP_API_KEY が存在し、tp- で始まることを確認。
    • 既に存在する場合、続行。
    • 存在しない場合、ユーザーにMiMo API Key(tp- で始まる)を尋ねる。
    • ユーザーからKeyを取得したら、以降の要約に関わる全てのコマンドで環境変数として渡す。例:
      set MIMO_TP_API_KEY=tp-xxxx
      node .claude/skills/rain-class-reviewer/scripts/bootstrap.js summarize --course-dir rain-class-reviewer-downloads/<コース名>
      
    • Keyをファイルに書き込むようユーザーに要求したり、スキルがKeyをディスクに書き込んだりすることを禁止する。
  4. ユーザーがダウンロード/要約するコース名を明示的に指定していることを確認する。

クイックスタート

全てのコマンドは、現在のClaude Code / OpenCodeプロジェクトルートで実行し、スキルディレクトリへの相対パスでスクリプトを呼び出します。scripts/bootstrap.js は自動的にプロジェクトルートを作業ディレクトリとみなします。そのため:

  • 相対パスの --manifest、-o、--course-dir、--lesson-dir などの引数は全てプロジェクトルートを基準に解決され、パスの重複は発生しません。
  • --output を指定しない場合、デフォルトのダウンロードディレクトリはプロジェクトルートの rain-class-reviewer-downloads/ 以下に生成され、スキルのインストールディレクトリの下ではありません。

初回呼び出し時、scripts/bootstrap.js はプリビルドされた dist/cli.cjs(既に openai などの依存関係を含む)を優先して使用するため、ネットワークインストールは不要です。存在しない場合のみ、自動的に npm install を実行します。

完全なフロー

1. ユーザーにコース名(またはキーワード)を尋ねる。
2. MCPで `https://changjiang.yuketang.cn/` を開き、Cookieを取得する(優先:Networkリクエストヘッダーから)。
3. 最小限のManifest JSONを構築し、`<skill-path>/tmp/manifest.json` に書き込む。
4. `node <skill-path>/scripts/bootstrap.js verify-auth --manifest <skill-path>/tmp/manifest.json` を実行し、ログイン状態を検証する。
5. `node <skill-path>/scripts/bootstrap.js list-courses --manifest <skill-path>/tmp/manifest.json --json` を実行し、コース一覧を取得する。
6. ユーザーの入力に基づいてコースをマッチングする。曖昧な場合、ユーザーに候補を表示し、classroomIdを確認する。
7. コース一覧から返された元のcourseNameを使用し、classroomIdを含むManifestを構築する(tmp/manifest.jsonを上書き)。`node <skill-path>/scripts/bootstrap.js --manifest <skill-path>/tmp/manifest.json --json` を実行し、ダウンロードする(デフォルト出力先は `rain-class-reviewer-downloads/`)。
8. `MIMO_TP_API_KEY` を設定した後、`node <skill-path>/scripts/bootstrap.js summarize --course-dir "rain-class-reviewer-downloads/<元のコース名>" --force-summary` を実行し、復習概要を生成する。

例(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

標準実行フロー

1. ユーザーが希望するコース名を取得する

ユーザーにコース名を確認します。略称やキーワード(例:「コンピュータネットワーク」)を許可します。ユーザーの元の入力を記録し、すぐにマッチングを行わないでください。

2. MCPを使用してCookieを取得する

长江雨课堂の sessionid は通常 HttpOnly Cookie であり、document.cookie では読み取れません。Chrome DevTools Networkリクエストヘッダーを介して取得する必要があり、以下にリストされたURLのみを厳密に使用する必要があります。

2.1 长江雨课堂のページを開く

ナビゲートする必要があるURL:

https://changjiang.yuketang.cn/

操作手順:

  1. ブラウザに接続する。
  2. mcp__chrome-devtools__navigate_page を使用して、次のURLにナビゲートする:
    https://changjiang.yuketang.cn/
    
  3. ページが既に読み込まれている場合、type=reload を使用して同じURLをリロードし、新しいネットワークリクエストを生成する:
    mcp__chrome-devtools__navigate_page: type=reload, url=https://changjiang.yuketang.cn/
    

2.2 Cookieを含むネットワークリクエストを1つトリガーする

ページのリロード後、ブラウザは自動的に複数のCookieを含むリクエストを生成することがよくあります。十分なリクエストが現れない場合、必ず以下のURLを能動的にトリガーする必要があります:

優先トリガーURL(このURLはスクリプトの後続の verify-auth / list-courses で使用されるコース一覧APIと完全に一致し、安全で再利用可能です):

GET https://changjiang.yuketang.cn/v2/api/web/courses/list?identity=2

トリガー方法(いずれかを選択。リクエストトラフィックを生成するためだけに使用し、レスポンスの業務データを読み取ることは禁止):

  • 方法A:ページリフレッシュを1回実行する(2.1を参照)。
  • 方法B:evaluate_script を介して実行する:
    fetch('https://changjiang.yuketang.cn/v2/api/web/courses/list?identity=2', { credentials: 'include' });
    

代替トリガーURL(優先リクエストが現れない場合、changjiang.yuketang.cn への任意のリクエストで可):

https://changjiang.yuketang.cn/            (ページドキュメント)
https://changjiang.yuketang.cn/v2/web/index (ホームページエントリ)
https://changjiang.yuketang.cn/*           (同一ドメイン下の静的リソース、JS/CSSなど)

禁止:他の雨课堂サブドメインやサードパーティAPIを使用してCookieをプローブすること。

2.3 NetworkリクエストヘッダーからCookieを読み取る

  1. list_network_requests を呼び出し、最近のリクエストを表示する。
  2. リクエストリストから、以下の優先順位で1つのリクエストを選択する:
    • 優先:https://changjiang.yuketang.cn/v2/api/web/courses/list?identity=2
    • 次点:https://changjiang.yuketang.cn/ または https://changjiang.yuketang.cn/v2/web/index
    • 許容:任意の https://changjiang.yuketang.cn/* リクエスト
  3. get_network_request を使用して、そのリクエストの Request Headers を読み取る。
  4. リクエストヘッダー内の cookie または Cookie フィールドを見つけ、以下のフィールドを解析する:
    • sessionid(必須)
    • csrftoken(推奨。CSRF検証用)
    • uv_id(実際の値に従って抽出。0 または他の値の可能性あり)
    • university_id(実際の値に従って抽出。uv_id と同じか異なる可能性あり)
    • xtbz(通常は ykt)
    • django_language(オプション)

Cookieヘッダーの例:

sessionid=abc123; csrftoken=xyz789; uv_id=0; university_id=0; xtbz=ykt

uv_id=2874 や university_id=2874 をハードコードしないでください。リクエストヘッダーから実際の値を読み取る必要があります。欠落または 0 は許可されます。

2.4 未ログイン状態の処理

  • リクエストヘッダーに sessionid がない場合、またはリクエストがログインページにリダイレクトされた場合、ユーザーはログインしていません。
  • ユーザーに长江雨课堂に手動でログインするよう促します。
  • ユーザーが「ログイン済み」と返信するのを待ちます。
  • ページをリロードするか、再度 https://changjiang.yuketang.cn/v2/api/web/courses/list?identity=2 をトリガーし、Cookieを再読み取りします。

2.5 フォールバック計画

MCPがリクエストヘッダー内のCookieを提供できない場合:

  1. document.cookie を読み取り、非HttpOnly Cookie(少なくとも csrftoken は取得できるはず)を取得してみます。
  2. それでも sessionid を取得できない場合、ユーザーに手動で sessionid を提供してもらうか、MCPがHttpOnly Cookieの取得をサポートしているか確認します。
  3. フォールバックが成功したかどうかに関わらず、最終的には必ずNetworkリクエストヘッダーを介して sessionid を取得する必要があります。

3. 最小限のManifestを構築する

{
  "version": "1.0",
  "courseName": "コンピュータネットワーク"
}

courseName にはユーザーの元の入力値を使用します。このManifestは検証とコース一覧取得のみに使用され、最終的なマッチングを保証するものではありません。このManifestを構築したら、直ちにMCPを停止します。

Cookieは RAIN_COOKIES 環境変数で渡します(以降同様):

set RAIN_COOKIES={"sessionid":"...","csrftoken":"...","uv_id":"0","university_id":"0","xtbz":"ykt"}

4. ログイン状態を検証する

set RAIN_COOKIES={...}
node <skill-path>/scripts/bootstrap.js verify-auth --manifest <skill-path>/tmp/manifest.json
  • 成功:次のステップに進む。
  • 失敗:ステップ2に戻り、Cookieを再取得する。

5. コース一覧を取得する

set RAIN_COOKIES={...}
node <skill-path>/scripts/bootstrap.js list-courses --manifest <skill-path>/tmp/manifest.json --json

現在のアカウント下の全コースの classroomId、courseName、className、teacher を返します。

6. コースをマッチングし、曖昧性を処理する

ユーザーの元の入力でコース一覧とマッチングします:

  • 一意の完全一致:その classroomId を直接使用する。
  • 一致なし:利用可能な全コースをユーザーに表示し、コース名または classroomId を指定するよう要求する。
  • 複数一致:候補コース(クラス、教師、classroomIdを含む)をユーザーに表示し、確認を要求する。

勝手に選択することを禁止します。 確認後、コース一覧から返された元の courseName を使用して新しいManifestを構築し、tmp/manifest.json に上書き書き込みます:

{
  "version": "1.0",
  "courseName": "コンピュータネットワーク",
  "classroomId": "13522533"
}

7. スライドをダウンロードする

set RAIN_COOKIES={...}
node <skill-path>/scripts/bootstrap.js --manifest <skill-path>/tmp/manifest.json --json

8. Markdownノートを抽出し、復習概要を生成する

set MIMO_TP_API_KEY=tp-xxxx
node <skill-path>/scripts/bootstrap.js summarize --course-dir "rain-class-reviewer-downloads/<コース名>" --force-summary

出力:

  • ページごとのMarkdownノート:rain-class-reviewer-downloads/<コース名>/extracted/<授業>/<ページ番号>.md
  • 全体の復習概要:rain-class-reviewer-downloads/<コース名>/review.md

授業単位でのフィルタリングダウンロード

最新の授業のみをダウンロード:

node <skill-path>/scripts/bootstrap.js --manifest <skill-path>/tmp/manifest.json --latest --json

日付範囲でダウンロード:

node <skill-path>/scripts/bootstrap.js --manifest <skill-path>/tmp/manifest.json --since 2023-11-01 --until 2023-11-05 --json

コース名の曖昧性処理

  • 同名のコースが複数存在する場合、スクリプトはエラーを報告し、候補の classroomId をリスト表示します。
  • 勝手に選択することを禁止します。必ずユーザーに候補コースを表示し、確認を要求します。
  • 確認後、Manifestで classroomId を明示的に指定してからスクリプトを呼び出します。

認証失敗の処理

スクリプトが403 / 未ログイン / 認証検証失敗を返した場合:

  1. sessionid が期限切れまたは欠落していることを説明します。
  2. ステップ2(MCPを使用して確認/再ログイン)を再実行します。
  3. RAIN_COOKIES 環境変数を更新します。
  4. スクリプトを再実行します。

Claude Code 自動モードに関する特別な注意

本スキルのManifestファイルにはCookieなどの資格情報は含まれなくなりました。Cookieは RAIN_COOKIES 環境変数のみで渡されます。したがって、Write(tmp/manifest.json) はコース名/classroomIdのみを書き込むため、通常はauto modeのファイル書き込みチェックを通過できます。

それでもauto modeが一時ファイルへの書き込みをブロックする場合、現在のプロジェクトルートに手動で .claude/policy.json を作成します:

{
  "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."
    ]
  }
}

全てのコマンドには 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

Git Bash / Linux / macOS では export RAIN_COOKIES='...' を使用します。

セキュリティとプライバシー

  • 会話中に完全なCookieを平文で出力することを禁止します。
  • Manifestはスキルディレクトリ下の tmp/manifest.json に上書き書き込みします。Manifestにcookiesフィールドを含めてはなりません。tmp/ は .gitignore に含まれているため、バージョン管理には入りません。
  • Cookieは RAIN_COOKIES 環境変数でのみ渡します。cookies.json を個別に保存しないでください。
  • ダウンロードディレクトリ rain-class-reviewer-downloads/ と一時ディレクトリ tmp/ は .gitignore に含まれています。

既知の制限

  • ツールは優先的に新しい lesson-summary + presentation APIを使用して完全なPPTを取得します。利用できない場合は自動的に review APIにフォールバックしますが、後者は授業中に表示されたスライドのみを含みます。
  • 要約機能はMiMo API Keyに依存し、MIMO_TP_API_KEY 環境変数で渡す必要があります。ファイルへの書き込みは禁止されています。

参考

  • references/yuketang-api.md:长江雨课堂API一覧と制約。
  • references/manifest.example.json:Manifest完全な例。
  • docs/usage.md:CLI完全なパラメータ説明。
  • docs/implementation.md:実装の詳細。

関連スキル