{"id":50979373,"url":"https://github.com/sah1l/chess-narrator","last_synced_at":"2026-06-19T12:33:57.712Z","repository":{"id":359823182,"uuid":"1247640849","full_name":"sah1l/chess-narrator","owner":"sah1l","description":"Turn any chess game into a narrated, animated MP4 explainer — Stockfish does the chess, AI does the teaching. Pieces slide move-to-move over a live evaluation bar, and the engine's mistakes and brilliancies are where the coach stops to talk. Installable as an AI-agent skill.","archived":false,"fork":false,"pushed_at":"2026-06-14T09:18:28.000Z","size":18855,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-14T11:09:04.208Z","etag":null,"topics":["agent-skill","ai-agents","chess","chess-analysis","claude","explainer-video","hyperframes","lichess","pgn","stockfish","text-to-speech","video-generation"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sah1l.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-23T15:31:43.000Z","updated_at":"2026-06-14T09:20:55.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sah1l/chess-narrator","commit_stats":null,"previous_names":["sah1l/chess-narrator"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sah1l/chess-narrator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sah1l%2Fchess-narrator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sah1l%2Fchess-narrator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sah1l%2Fchess-narrator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sah1l%2Fchess-narrator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sah1l","download_url":"https://codeload.github.com/sah1l/chess-narrator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sah1l%2Fchess-narrator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34532255,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-19T02:00:06.005Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-skill","ai-agents","chess","chess-analysis","claude","explainer-video","hyperframes","lichess","pgn","stockfish","text-to-speech","video-generation"],"created_at":"2026-06-19T12:33:55.053Z","updated_at":"2026-06-19T12:33:57.664Z","avatar_url":"https://github.com/sah1l.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# chess-narrator\n\nTurn a chess game into a narrated MP4 explainer video — continuous gameplay where the pieces slide move-to-move and the evaluation bar rises and falls live. Stockfish handles the chess. Claude handles the teaching. Edge-tts and HyperFrames handle the delivery.\n\nDesigned for intermediate club players who want to understand *why* a game went the way it did — not just see the moves played. Obvious moves slide by; the engine's mistakes, brilliancies, and turning points are where the coach stops to talk — so a typical game runs 5–7 minutes.\n\n![Node](https://img.shields.io/badge/Node-%3E%3D22-339933) ![Stockfish](https://img.shields.io/badge/Stockfish-18-lightgrey) ![License](https://img.shields.io/badge/license-MIT-blue)\n\n## Sample videos\n\n- [Morphy's Opera Game (Paris, 1858)](https://youtu.be/YFo5eR5-g_8) — the canonical attacking miniature\n- [My queen went on a pawn-grabbing road trip behind enemy lines](https://youtu.be/9Kj2KtpoAjc) — a personal game walkthrough\n\n## What it produces\n\nA 1920×1080 MP4, typically 5–7 minutes, that:\n\n- Opens with a title card and a scene-setting intro\n- Walks through **every move** with tiered commentary (book / routine / interesting / critical)\n- Visually marks mistakes, brilliancies, and engine alternatives\n- Pauses at one critical position and asks the viewer to find the move themselves (\"What would you play here?\"), then explains why each plausible-looking alternative fails before revealing the answer\n- Closes with an outro that lands the lesson\n\n## Install as an agent skill\n\nThis repo is an agent skill compatible with GitHub Copilot, Claude Code, Cursor, OpenCode, Windsurf, and [many other AI coding agents](https://cli.github.com/manual/gh_skill_install). Install it with the GitHub CLI's skill subcommand (currently in preview), then run `npm install` + `verify` to set up the Node side.\n\nThe skill lives at [`skills/chess-narrator/`](skills/chess-narrator) in this repo. `gh skill install` reads that path and drops it into your agent's skills directory.\n\n**Project-scoped (only inside the current repo, default):**\n\n```bash\ngh skill install sah1l/chess-narrator chess-narrator --agent \u003cyour-agent\u003e\ncd .agents/skills/chess-narrator\nnpm install\nnode src/cli.js verify\n```\n\n**User-scoped (available in every project on your machine):**\n\n```bash\ngh skill install sah1l/chess-narrator chess-narrator --agent \u003cyour-agent\u003e --scope user\n# gh prints the install path — cd into it, then:\nnpm install\nnode src/cli.js verify\n```\n\n**Pin to a version / commit** (avoid surprise updates):\n\n```bash\ngh skill install sah1l/chess-narrator chess-narrator --agent \u003cyour-agent\u003e --pin \u003ctag-or-sha\u003e\n```\n\n\u003e Replace `\u003cyour-agent\u003e` with your AI coding agent: `claude-code`, `opencode`, `github-copilot`, `cursor`, `windsurf`, etc. See the [full list of supported agents](https://cli.github.com/manual/gh_skill_install#gh-skill-install).\n\n**Update later:**\n\n```bash\ngh skill update chess-narrator\n# or all skills at once:\ngh skill update --all\n```\n\n\u003e `gh skill` is in preview and ships in recent `gh` builds. If your `gh` doesn't have it yet, use the clone fallback below.\n\n\u003cdetails\u003e\n\u003csummary\u003eFallback: plain \u003ccode\u003egit clone\u003c/code\u003e (no \u003ccode\u003egh skill\u003c/code\u003e)\u003c/summary\u003e\n\nClone the whole repo and work directly inside the skill directory:\n\n```bash\ngit clone https://github.com/sah1l/chess-narrator\ncd chess-narrator/skills/chess-narrator\nnpm install \u0026\u0026 node src/cli.js verify\n```\n\nTo wire it up as an agent skill without `gh`, copy or symlink the `skills/chess-narrator/` directory into `.agents/skills/chess-narrator/` (project scope) or your user-scoped agent skills dir.\n\u003c/details\u003e\n\nOnce installed, just say things like *\"make a video of this Lichess game: https://lichess.org/abc123\"* or *\"explain this PGN as a walkthrough\"* and your agent will run the pipeline. See [`skills/chess-narrator/SKILL.md`](skills/chess-narrator/SKILL.md) for the full trigger surface.\n\n## Verify your setup\n\nThe skill ships with a one-shot env check that tells you exactly what's missing and how to install it:\n\n```bash\nnode src/cli.js verify\n# or\nnpm run verify\n```\n\nSample output on a healthy machine:\n\n```\nchess-narrator environment check\n\n  [OK]   Node ≥22                 — v22.22.3\n  [OK]   stockfish (npm)\n  [OK]   chess.js (npm)\n  [OK]   msedge-tts (npm)\n  [OK]   ffmpeg on PATH           — ffmpeg version 6.1.1\n  [OK]   Chrome/Edge/Chromium     — /Applications/Google Chrome.app/…\n  [OK]   hyperframes CLI          — cached v0.6.97 (default renderer)\n  [OK]   edge-tts reachable       — speech.platform.bing.com\n\nAll required dependencies present.\n```\n\nWhen you ask Claude *\"verify chess-narrator\"* (or *\"check the chess-narrator setup\"*, *\"is everything installed?\"*), it will run this command and walk you through any `[MISS]` items. Use `--skip-network` to skip the edge-tts reachability probe.\n\nRequired: Node 22+, ffmpeg on PATH, Chrome / Chromium / Edge. The npm deps install via `npm install`. The HyperFrames CLI (default renderer) is fetched via `npx` on first render — it shows as `[WARN]` until then and isn't required (the ffmpeg renderer is the offline fallback). The edge-tts network check is optional — only needed if you plan to use `--engine edge` for neural-voice narration.\n\n## Quick start\n\n```bash\n# 1. Clone + install (skip if already installed as a skill above)\ngit clone https://github.com/sah1l/chess-narrator\ncd chess-narrator/skills/chess-narrator\nnpm install\nnode src/cli.js verify\n\n# 2. Analyze a game\nnode src/cli.js analyze samples/sample-game.pgn\n# → samples/output/annotation.json\n\n# 3. (Have Claude write narration.json — see the SKILL.md prompt)\n# Or use the bundled sample:\ncp samples/sample-narration.json my-narration.json\n\n# 4. Build the shot list\nnode src/cli.js build-script samples/output/annotation.json my-narration.json\n# → samples/output/script.json\n\n# 5. Synthesize audio (edge-tts neural voices, free, requires internet)\nnode src/cli.js synthesize samples/output/script.json --engine edge\n# → samples/output/script.audio.json + samples/output/audio/*.wav\n\n# 6. Render the MP4 (default renderer = hyperframes, continuous animation;\n#    fetched via npx on first use. Add --renderer ffmpeg for the offline still fallback.)\nnode src/cli.js render samples/output/script.audio.json --mp4 video.mp4\n# → video.mp4\n```\n\n## Architecture\n\n```\n                     ┌─────────────────┐\n   PGN / URL / FEN ──┤   Input Loader  │── normalized game/position\n                     └────────┬────────┘\n                              │\n                     ┌────────▼────────┐\n                     │    Stockfish    │  multipv at sweep depth 10,\n                     │   (truth layer) │  deep re-eval at depth 18\n                     └────────┬────────┘\n                              │  annotation.json\n                              │  ── per-ply evals, classifications\n                              │  ── key moments (4-7 per game)\n                              │  ── one challenge pick (or null)\n                              ▼\n                     ┌─────────────────┐\n                     │     Claude      │  one segment per ply, paced\n                     │ (teacher layer) │  silent / brief / full + challenge\n                     └────────┬────────┘\n                              │  narration.json (validated)\n                              ▼\n                     ┌─────────────────┐\n                     │  Shot Builder   │  ply → shot mapping; recomputes pace\n                     │                 │  challenge expansion (5 shots)\n                     └────────┬────────┘\n                              │  script.json\n                              ▼\n                     ┌─────────────────┐    edge-tts → MP3 → ffmpeg → WAV\n                     │      TTS        │\n                     └────────┬────────┘\n                              │  script.audio.json + audio/*.wav\n                              ▼\n                     ┌─────────────────┐  hyperframes (default): one animated\n                     │    Renderer     │  composition (sliding pieces + live\n                     │                 │  eval bar) → deterministic MP4.\n                     └────────┬────────┘  ffmpeg fallback: still slideshow.\n                              │\n                              ▼\n                          video.mp4\n```\n\n## Why three layers?\n\nHard separation of concerns:\n\n- **Truth layer (Stockfish)** never speculates. Numbers in, numbers out. Cached on disk so re-runs are free.\n- **Teacher layer (Claude)** is constrained — must consume the structured briefing, cannot invent threats, cannot override evaluations. Coach voice over engine analysis.\n- **Delivery layer** is dumb. Takes the shot list and produces a video; no chess knowledge required. The default renderer builds one HyperFrames composition and renders it deterministically; an ffmpeg still-slideshow renderer remains as an offline fallback.\n\nThis means you can swap any layer independently: try Leela instead of Stockfish, GPT instead of Claude, or another renderer instead of HyperFrames.\n\n## Inputs\n\n```bash\n# PGN file\nnode src/cli.js analyze game.pgn\n\n# Lichess game URL\nnode src/cli.js analyze https://lichess.org/abc123\n\n# Chess.com game URL\nnode src/cli.js analyze https://www.chess.com/game/live/12345678\n\n# Raw FEN (single-position mode — different narration shape)\nnode src/cli.js analyze --fen \"r1bq1rk1/pppp1ppp/2n2n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQ - 6 6\"\n\n# Inline PGN text via stdin / temp file\n```\n\n## TTS voice options\n\nThe `edge` engine uses Microsoft's free neural voices. Default is `en-US-AndrewMultilingualNeural` (warm narrator). Other strong choices for chess commentary:\n\n```bash\nnode src/cli.js synthesize script.json --engine edge --voice en-US-GuyNeural          # clear broadcast\nnode src/cli.js synthesize script.json --engine edge --voice en-US-ChristopherNeural  # deeper, authoritative\nnode src/cli.js synthesize script.json --engine edge --voice en-US-DavisNeural        # younger\nnode src/cli.js list-voices --engine edge   # ~500 voices across languages\n```\n\nFalls back to Windows SAPI 5 with `--engine system` if you have no internet (sounds robotic).\n\n## What this skill is NOT\n\n- Not an opening trainer or repertoire builder\n- Not a tactics puzzle generator (though the \"pause and think\" feature gives you one puzzle per game)\n- Not real-time commentary — analysis takes ~2 min per game at default depth\n- Not a chess engine — it's a wrapper over Stockfish\n\n## Dependencies\n\n- **Node ≥22** (ES modules, `node:test`)\n- **chess.js ^1.4.0** — PGN parsing, SAN↔UCI, FEN validation\n- **stockfish ^18.0.7** — engine (lite-single flavor, runs in-process)\n- **msedge-tts ^2** — edge-tts WebSocket client\n- **ffmpeg** on PATH — audio conversion + the ffmpeg fallback renderer\n- **Chrome / Chromium** on PATH — the ffmpeg renderer's headless board screenshots\n- **HyperFrames CLI** — the default continuous renderer; auto-fetched via `npx hyperframes` on first render (internet once, then cached; brings its own Chromium + ffmpeg)\n\n## Tests\n\n```bash\nnpm test\n# 69 tests across annotate, classify, narrate, render, hyperframes, tts\n```\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n\n## Acknowledgments\n\n- Stockfish, the open-source engine that does the actual chess work\n- chess.js, for keeping PGN parsing pleasant\n- The Opera Game (Morphy vs Karl/Isouard, Paris 1858), used as the canonical sample because it's the most famous attacking game ever played and demonstrates every tier of commentary the pipeline produces\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsah1l%2Fchess-narrator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsah1l%2Fchess-narrator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsah1l%2Fchess-narrator/lists"}