[{"data":1,"prerenderedAt":1683},["ShallowReactive",2],{"repo-tree":3,"repo-\u002F.claude\u002Fskills\u002Feval-playground\u002Fskill":283},[4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58,61,64,67,69,72,75,78,81,84,86,88,90,93,96,99,102,105,108,111,114,117,120,123,125,127,129,131,133,135,138,141,143,146,149,152,155,158,161,164,167,169,172,175,178,180,183,186,189,192,195,198,201,203,206,209,212,215,218,221,224,227,230,233,236,239,242,245,248,251,254,257,260,263,266,269,272,275,278,281],{"path":5,"title":6},"\u002Fagents\u002Fbackend-code-style","Backend Conventions",{"path":8,"title":9},"\u002Fagents\u002Fdatabase","Database",{"path":11,"title":12},"\u002Fagents\u002Fportal-code-style","Portal Conventions",{"path":14,"title":15},"\u002Fagents\u002Ftranslation","Translation",{"path":17,"title":18},"\u002Fconventions\u002Fbackend-coding","Backend coding conventions",{"path":20,"title":21},"\u002Fconventions\u002Ffrontend-coding","Frontend coding conventions",{"path":23,"title":24},"\u002Fdevelopment-process","Development process",{"path":26,"title":27},"\u002Flearning-api-preview-hetzner-setup","Learning API Preview on Hetzner + Cloudflare",{"path":29,"title":30},"\u002Flearning-api-preview-vm-plan","Learning API Preview VM Plan",{"path":32,"title":33},"\u002Fmonorepo-structure","Monorepo structure",{"path":35,"title":36},"\u002Foperations","Operations — bugs and support",{"path":38,"title":39},"\u002Fpostmortems\u002F2026-03-16_onboarding-currency-regression","Onboarding Zod transform silently broken — web signups assigned wrong checkout currency",{"path":41,"title":42},"\u002Fpostmortems\u002Freadme","Postmortems",{"path":44,"title":45},"\u002Fpostmortems\u002F_template","TEMPLATE",{"path":47,"title":48},"\u002Fpostmortems\u002Fposthog-comparison","Postmortem practice — comparison with PostHog",{"path":50,"title":51},"\u002Fpreview-environment-plan","Preview Environment Plan",{"path":53,"title":54},"\u002Fprinciples","Engineering principles",{"path":56,"title":57},"\u002Fworking-with-ai","Working with AI",{"path":59,"title":60},"\u002F.claude\u002Fskills\u002Feval-playground\u002Fskill","Eval Playground — Co-development Skill",{"path":62,"title":63},"\u002F.claude\u002Fskills\u002Ffigma-diff-section\u002Fskill","Figma Diff Section Pipeline",{"path":65,"title":66},"\u002Fagents","AGENTS.md",{"path":68,"title":66},"\u002Fclaude",{"path":70,"title":71},"\u002Freadme","Studyflash",{"path":73,"title":74},"\u002Fapps\u002Fcore-api\u002Fagents","Core API (apps\u002Fcore-api)",{"path":76,"title":77},"\u002Fapps\u002Fcore-api\u002Freadme","README",{"path":79,"title":80},"\u002Fapps\u002Femail-previews\u002Fagents","Email Previews (apps\u002Femail-previews)",{"path":82,"title":83},"\u002Fapps\u002Flanding-page\u002Fagents","Landing Page (apps\u002Flanding-page)",{"path":85,"title":83},"\u002Fapps\u002Flanding-page\u002Fclaude",{"path":87,"title":66},"\u002Fapps\u002Flearning-api\u002Fagents",{"path":89,"title":77},"\u002Fapps\u002Flearning-api\u002Freadme",{"path":91,"title":92},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Feval_metrics_design","Surface-Specific Eval Metrics Design",{"path":94,"title":95},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Ftest_set","Quiz Eval Test Set",{"path":97,"title":98},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Ffrontend\u002Freadme","React + TypeScript + Vite",{"path":100,"title":101},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Fknown-issues\u002Fcontent-pillar-shallow-coverage\u002Freadme","Content pillar misses subtopics in dense documents",{"path":103,"title":104},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Fknown-issues\u002Fdocling-empty-section-headers\u002Freadme","Empty section headers dropped by docling chunker",{"path":106,"title":107},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Fknown-issues\u002Fdocling-table-reading-order\u002Freadme","Table\u002Fbox layout causes wrong reading order",{"path":109,"title":110},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Fmetrics\u002Freadme","Quiz eval metrics — canonical rubrics",{"path":112,"title":113},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Freports\u002F2026-04-12-quiz-summary-feedback-current-state","Quiz and Summary Feedback Current State",{"path":115,"title":116},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Freports\u002F2026-04-24-quiz-eval-metrics","Quiz Evaluation Metrics",{"path":118,"title":119},"\u002Fapps\u002Flearning-api\u002Fevals-playground\u002Freports\u002F2026-05-01-quiz-eval-current-state","Quiz Eval Current State",{"path":121,"title":122},"\u002Fapps\u002Flearning-api\u002Fmonitoring\u002Freadme","Monitoring Stack",{"path":124,"title":77},"\u002Fapps\u002Flearning-api\u002Fshared\u002Freadme",{"path":126,"title":77},"\u002Fapps\u002Flearning-api\u002Fworkers\u002Flearning_agents\u002Fflashcard_agent\u002Freadme",{"path":128,"title":77},"\u002Fapps\u002Flearning-api\u002Fworkers\u002Flearning_agents\u002Fingestion_agent\u002Freadme",{"path":130,"title":77},"\u002Fapps\u002Flearning-api\u002Fworkers\u002Flearning_agents\u002Fquiz_agent\u002Freadme",{"path":132,"title":77},"\u002Fapps\u002Flearning-api\u002Fworkers\u002Flearning_agents\u002Fsummary_agent\u002Freadme",{"path":134,"title":77},"\u002Fapps\u002Flearning-api\u002Fworkers\u002Fparser\u002Freadme",{"path":136,"title":137},"\u002Fapps\u002Fmarketing-emails-preview\u002Fagents","Marketing Emails Preview (apps\u002Fmarketing-emails-preview)",{"path":139,"title":140},"\u002Fapps\u002Fmobile-app\u002Fagents","StudyFlash Mobile App - Claude Code Configuration",{"path":142,"title":140},"\u002Fapps\u002Fmobile-app\u002Fclaude",{"path":144,"title":145},"\u002Fapps\u002Fmountain-max\u002Fagents","Mountain Max (apps\u002Fmountain-max)",{"path":147,"title":148},"\u002Fapps\u002Fmountain-max\u002Fgame\u002Freadme","Mountain Max Game",{"path":150,"title":151},"\u002Fapps\u002Fportal\u002Fagents","Portal (apps\u002Fportal)",{"path":153,"title":154},"\u002Fapps\u002Fportal\u002Freadme","Nuxt Minimal Starter",{"path":156,"title":157},"\u002Fapps\u002Fportal\u002Fapp\u002Fcomposables\u002Ffiles\u002Freadme","File Upload Composables",{"path":159,"title":160},"\u002Fapps\u002Fportal\u002Fdocs\u002Flibrary-routing","Library Routing Documentation",{"path":162,"title":163},"\u002Fapps\u002Fsupabase\u002Fagents","Supabase (apps\u002Fsupabase)",{"path":165,"title":166},"\u002Fapps\u002Fwrapped\u002Fagents","Wrapped (apps\u002Fwrapped)",{"path":168,"title":98},"\u002Fapps\u002Fwrapped\u002Freadme",{"path":170,"title":171},"\u002Finfra\u002Freadme","infra\u002F",{"path":173,"title":174},"\u002Finfra\u002Fdns\u002Freadme","DNS Infrastructure",{"path":176,"title":177},"\u002Finfra\u002Fdokploy\u002Freadme","studyflash-dokploy",{"path":179,"title":77},"\u002Finfra\u002Fdokploy\u002Fsdk\u002Fnodejs\u002Freadme",{"path":181,"title":182},"\u002Finfra\u002Finfisical\u002Freadme","Infisical Infrastructure",{"path":184,"title":185},"\u002Finfra\u002Flearning-api\u002Freadme","Pulumi GCP TypeScript Template",{"path":187,"title":188},"\u002Finfra\u002Fopenreplay\u002Freadme","OpenReplay on Hetzner",{"path":190,"title":191},"\u002Finfra\u002Fscripts\u002Freadme","infra\u002Fscripts\u002F",{"path":193,"title":194},"\u002Finfra\u002Fturborepo-cache\u002Freadme","Turborepo Remote Cache Infrastructure",{"path":196,"title":197},"\u002Finternal\u002Fchatwoot\u002Freadme","Chatwoot Infrastructure",{"path":199,"title":200},"\u002Finternal\u002Fchatwoot\u002Fprovider\u002Freadme","studyflash-chatwoot-provider",{"path":202,"title":77},"\u002Finternal\u002Fchatwoot\u002Fprovider\u002Fsdk\u002Fnodejs\u002Freadme",{"path":204,"title":205},"\u002Finternal\u002Fdocs\u002Freadme","internal\u002Fdocs",{"path":207,"title":208},"\u002Finternal\u002Fsupport-bot\u002Fclaude","Support Bot (Maximilian)",{"path":210,"title":211},"\u002Finternal\u002Fsupport-bot\u002Freadme","Studyflash Customer Support Bot (Maximilian)",{"path":213,"title":214},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Faccount_issues","Account Issues",{"path":216,"title":217},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fbilling_invoice","Billing Invoice",{"path":219,"title":220},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fcontent_upload","Content Upload",{"path":222,"title":223},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fdata_loss","Data Loss",{"path":225,"title":226},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fflashcard_issues","Flashcard Issues",{"path":228,"title":229},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fgarbage","Garbage",{"path":231,"title":232},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fgeneral_how_to","General How To",{"path":234,"title":235},"\u002Finternal\u002Fsupport-bot\u002Fkb","Knowledge Base Index",{"path":237,"title":238},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Flanguage_issues","Language Issues",{"path":240,"title":241},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fmindmap_issues","Mindmap Issues",{"path":243,"title":244},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fmisunderstanding","Misunderstanding",{"path":246,"title":247},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fmock_exam_issues","Mock Exam Issues",{"path":249,"title":250},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fpodcast_issues","Podcast Issues",{"path":252,"title":253},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fquiz_issues","Quiz Issues",{"path":255,"title":256},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Frefund_request","Refund Request",{"path":258,"title":259},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fsubscription_cancellation","Subscription Cancellation",{"path":261,"title":262},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fsubscription_info","Subscription Info",{"path":264,"title":265},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fsummary_issues","Summary Issues",{"path":267,"title":268},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Ftechnical_errors","Technical Errors",{"path":270,"title":271},"\u002Finternal\u002Fsupport-bot\u002Fkb\u002Fvideo_issues","Video Issues",{"path":273,"title":274},"\u002Fpackages\u002Fcommon\u002Fdocs\u002Fearly-access-features","Declarative Early Access Features",{"path":276,"title":277},"\u002Fpackages\u002Fcommon\u002Fscripts\u002Freadme","Common Package Scripts",{"path":279,"title":280},"\u002Fpackages\u002Fdevtools\u002Ffigma-plugins\u002Freadme","Figma plugins",{"path":282,"title":77},"\u002Fpackages\u002Fpulumi-infisical\u002Freadme",{"id":284,"title":60,"body":285,"description":1674,"extension":1675,"lastReviewed":1676,"meta":1677,"navigation":376,"owner":1676,"path":59,"seo":1680,"status":1676,"stem":1681,"tags":1676,"__hash__":1682},"repo\u002F.claude\u002Fskills\u002Feval-playground\u002FSKILL.md",{"type":286,"value":287,"toc":1655},"minimark",[288,292,296,301,312,318,322,333,410,425,429,432,474,488,492,502,969,992,997,1004,1139,1155,1159,1341,1345,1348,1352,1355,1369,1373,1376,1402,1406,1409,1416,1420,1423,1427,1430,1434,1441,1468,1471,1502,1509,1513,1524,1541,1563,1568,1584,1594,1600,1606,1610,1651],[289,290,60],"h1",{"id":291},"eval-playground-co-development-skill",[293,294,295],"p",{},"You are co-developing AI generation features with the user. The eval playground is a full-stack tool for inspecting and iterating on the AI pipeline: parsing, chunking, content pillars, flashcards, quizzes, summaries, podcasts, and mindmaps.",[297,298,300],"h2",{"id":299},"architecture","Architecture",[302,303,308],"pre",{"className":304,"code":306,"language":307},[305],"language-text","                            Supabase + Celery workers\n                                       ▲\n                                       │\n                               app.py (FastAPI, port 8100)\n                                       ▲\n                          ┌────────────┴────────────┐\n                          │                         │\n                Web UI (port 5174)                cli.py\n                  (React)                         (Typer; you run this)\n","text",[309,310,306],"code",{"__ignoreMap":311},"",[293,313,314,317],{},[309,315,316],{},"app.py"," is the canonical API — it owns all reads\u002Fwrites against Supabase and dispatches generation tasks to workers. Web UI and CLI are both thin clients over the API. Inspection (decks\u002Fpillars\u002Fchunks\u002Fmindmap) and orchestration (ingest, generate, evaluate) all flow through HTTP. The CLI is what you (the agent) use to drive the pipeline.",[297,319,321],{"id":320},"running-the-playground","Running the playground",[293,323,324,325,328,329,332],{},"The playground server must be running for any CLI work — ",[309,326,327],{},"poe dev-eval-playground"," from ",[309,330,331],{},"apps\u002Flearning-api\u002F",". If it's not up, ask the user to start it before you try anything.",[302,334,338],{"className":335,"code":336,"language":337,"meta":311,"style":311},"language-bash shiki shiki-themes github-light github-dark","# User runs this once at the start of a session:\ncd apps\u002Flearning-api && poe dev-eval-playground\n\n# You run CLI commands from the playground dir:\ncd apps\u002Flearning-api\u002Fevals-playground\nuv run python cli.py --help\n","bash",[309,339,340,349,371,378,384,392],{"__ignoreMap":311},[341,342,345],"span",{"class":343,"line":344},"line",1,[341,346,348],{"class":347},"sJ8bj","# User runs this once at the start of a session:\n",[341,350,352,356,360,364,368],{"class":343,"line":351},2,[341,353,355],{"class":354},"sj4cs","cd",[341,357,359],{"class":358},"sZZnC"," apps\u002Flearning-api",[341,361,363],{"class":362},"sVt8B"," && ",[341,365,367],{"class":366},"sScJk","poe",[341,369,370],{"class":358}," dev-eval-playground\n",[341,372,374],{"class":343,"line":373},3,[341,375,377],{"emptyLinePlaceholder":376},true,"\n",[341,379,381],{"class":343,"line":380},4,[341,382,383],{"class":347},"# You run CLI commands from the playground dir:\n",[341,385,387,389],{"class":343,"line":386},5,[341,388,355],{"class":354},[341,390,391],{"class":358}," apps\u002Flearning-api\u002Fevals-playground\n",[341,393,395,398,401,404,407],{"class":343,"line":394},6,[341,396,397],{"class":366},"uv",[341,399,400],{"class":358}," run",[341,402,403],{"class":358}," python",[341,405,406],{"class":358}," cli.py",[341,408,409],{"class":354}," --help\n",[293,411,412,413,416,417,420,421,424],{},"The CLI defaults to ",[309,414,415],{},"http:\u002F\u002Flocalhost:8100","; override via ",[309,418,419],{},"--api-url"," or ",[309,422,423],{},"EVAL_PLAYGROUND_URL"," if the user is pointing at a remote dev\u002Fstaging server.",[297,426,428],{"id":427},"extending-the-playground-do-this-dont-work-around","Extending the playground (do this; don't work around)",[293,430,431],{},"The CLI is intentionally a thin client over the REST API. When you need a capability that isn't there:",[433,434,435,443,471],"ol",{},[436,437,438,442],"li",{},[439,440,441],"strong",{},"Don't"," drop down to direct Supabase queries, one-off scripts, or a parallel pipeline.",[436,444,445,448,449],{},[439,446,447],{},"Do"," extend the chain end-to-end:\n",[450,451,452,463,468],"ul",{},[436,453,454,455,458,459,462],{},"Add or extend the metric \u002F generation \u002F inspection logic in the right module (",[309,456,457],{},"metrics\u002F",", ",[309,460,461],{},"sdk.py",", generator code, etc.)",[436,464,465,466],{},"Expose it as a REST endpoint in ",[309,467,316],{},[436,469,470],{},"Add a thin CLI wrapper that calls the endpoint",[436,472,473],{},"The web UI gets it for free because it shares the API.",[293,475,476,477,479,480,483,484,487],{},"When you do this, tell the user explicitly what you're adding and why so the extension gets reviewed deliberately rather than tacked on. New endpoints go in ",[309,478,316],{},"; new schemas in ",[309,481,482],{},"api_models.py","; new CLI commands in ",[309,485,486],{},"cli.py",".",[297,489,491],{"id":490},"cli-reference","CLI Reference",[293,493,494,495,498,499,501],{},"All commands run from ",[309,496,497],{},"apps\u002Flearning-api\u002Fevals-playground\u002F",". Everything routes through ",[309,500,316],{}," over HTTP.",[302,503,505],{"className":335,"code":504,"language":337,"meta":311,"style":311},"# Decks\nuv run python cli.py decks                          # list decks\nuv run python cli.py decks --pillars                # only decks with content pillars\n\n# Content pillars\nuv run python cli.py pillars \u003Cdeck_id>              # content pillar tree (with excluded chunks)\nuv run python cli.py chunks \u003Cdeck_id>               # raw docling chunks with labels\u002Fheadings\nuv run python cli.py pillars-regenerate \u003Cdeck_id>   # re-run pillar generation (calls LLM)\nuv run python cli.py pillars-regenerate \u003Cdeck_id> --no-exclude --no-summaries\nuv run python cli.py pillars-compare \u003Cdeck_id>      # with vs without exclusion\nuv run python cli.py pillars-scan                   # scan all decks for exclusions\n\n# Mindmaps\nuv run python cli.py mindmap show \u003Cdeck_id>         # current mindmap as tree\nuv run python cli.py mindmap compare-excluded \u003Cdeck_id>  # with vs without excluded chunks\nuv run python cli.py mindmap json \u003Cdeck_id>         # Mind Elixir JSON\nuv run python cli.py mindmap json \u003Cdeck_id> --raw   # plain JSON for piping\nuv run python cli.py mindmap stats \u003Cdeck_id>        # quick numbers\nuv run python cli.py mindmap pillars-json \u003Cdeck_id> # raw content pillar input\n\n# Flashcard evals\nuv run python cli.py evaluate-flashcards \u003Cdeck_id>  # run flashcard evals on a deck\nuv run python cli.py evaluate-flashcards \u003Cdeck_id> --metrics blueprint_coverage,relevance\nuv run python cli.py evaluate-flashcards \u003Cdeck_id> --json   # raw JSON for piping\n",[309,506,507,512,528,546,550,555,584,609,634,661,686,703,708,714,742,769,796,825,852,879,884,890,915,942],{"__ignoreMap":311},[341,508,509],{"class":343,"line":344},[341,510,511],{"class":347},"# Decks\n",[341,513,514,516,518,520,522,525],{"class":343,"line":351},[341,515,397],{"class":366},[341,517,400],{"class":358},[341,519,403],{"class":358},[341,521,406],{"class":358},[341,523,524],{"class":358}," decks",[341,526,527],{"class":347},"                          # list decks\n",[341,529,530,532,534,536,538,540,543],{"class":343,"line":373},[341,531,397],{"class":366},[341,533,400],{"class":358},[341,535,403],{"class":358},[341,537,406],{"class":358},[341,539,524],{"class":358},[341,541,542],{"class":354}," --pillars",[341,544,545],{"class":347},"                # only decks with content pillars\n",[341,547,548],{"class":343,"line":380},[341,549,377],{"emptyLinePlaceholder":376},[341,551,552],{"class":343,"line":386},[341,553,554],{"class":347},"# Content pillars\n",[341,556,557,559,561,563,565,568,572,575,578,581],{"class":343,"line":394},[341,558,397],{"class":366},[341,560,400],{"class":358},[341,562,403],{"class":358},[341,564,406],{"class":358},[341,566,567],{"class":358}," pillars",[341,569,571],{"class":570},"szBVR"," \u003C",[341,573,574],{"class":358},"deck_i",[341,576,577],{"class":362},"d",[341,579,580],{"class":570},">",[341,582,583],{"class":347},"              # content pillar tree (with excluded chunks)\n",[341,585,587,589,591,593,595,598,600,602,604,606],{"class":343,"line":586},7,[341,588,397],{"class":366},[341,590,400],{"class":358},[341,592,403],{"class":358},[341,594,406],{"class":358},[341,596,597],{"class":358}," chunks",[341,599,571],{"class":570},[341,601,574],{"class":358},[341,603,577],{"class":362},[341,605,580],{"class":570},[341,607,608],{"class":347},"               # raw docling chunks with labels\u002Fheadings\n",[341,610,612,614,616,618,620,623,625,627,629,631],{"class":343,"line":611},8,[341,613,397],{"class":366},[341,615,400],{"class":358},[341,617,403],{"class":358},[341,619,406],{"class":358},[341,621,622],{"class":358}," pillars-regenerate",[341,624,571],{"class":570},[341,626,574],{"class":358},[341,628,577],{"class":362},[341,630,580],{"class":570},[341,632,633],{"class":347},"   # re-run pillar generation (calls LLM)\n",[341,635,637,639,641,643,645,647,649,651,653,655,658],{"class":343,"line":636},9,[341,638,397],{"class":366},[341,640,400],{"class":358},[341,642,403],{"class":358},[341,644,406],{"class":358},[341,646,622],{"class":358},[341,648,571],{"class":570},[341,650,574],{"class":358},[341,652,577],{"class":362},[341,654,580],{"class":570},[341,656,657],{"class":354}," --no-exclude",[341,659,660],{"class":354}," --no-summaries\n",[341,662,664,666,668,670,672,675,677,679,681,683],{"class":343,"line":663},10,[341,665,397],{"class":366},[341,667,400],{"class":358},[341,669,403],{"class":358},[341,671,406],{"class":358},[341,673,674],{"class":358}," pillars-compare",[341,676,571],{"class":570},[341,678,574],{"class":358},[341,680,577],{"class":362},[341,682,580],{"class":570},[341,684,685],{"class":347},"      # with vs without exclusion\n",[341,687,689,691,693,695,697,700],{"class":343,"line":688},11,[341,690,397],{"class":366},[341,692,400],{"class":358},[341,694,403],{"class":358},[341,696,406],{"class":358},[341,698,699],{"class":358}," pillars-scan",[341,701,702],{"class":347},"                   # scan all decks for exclusions\n",[341,704,706],{"class":343,"line":705},12,[341,707,377],{"emptyLinePlaceholder":376},[341,709,711],{"class":343,"line":710},13,[341,712,713],{"class":347},"# Mindmaps\n",[341,715,717,719,721,723,725,728,731,733,735,737,739],{"class":343,"line":716},14,[341,718,397],{"class":366},[341,720,400],{"class":358},[341,722,403],{"class":358},[341,724,406],{"class":358},[341,726,727],{"class":358}," mindmap",[341,729,730],{"class":358}," show",[341,732,571],{"class":570},[341,734,574],{"class":358},[341,736,577],{"class":362},[341,738,580],{"class":570},[341,740,741],{"class":347},"         # current mindmap as tree\n",[341,743,745,747,749,751,753,755,758,760,762,764,766],{"class":343,"line":744},15,[341,746,397],{"class":366},[341,748,400],{"class":358},[341,750,403],{"class":358},[341,752,406],{"class":358},[341,754,727],{"class":358},[341,756,757],{"class":358}," compare-excluded",[341,759,571],{"class":570},[341,761,574],{"class":358},[341,763,577],{"class":362},[341,765,580],{"class":570},[341,767,768],{"class":347},"  # with vs without excluded chunks\n",[341,770,772,774,776,778,780,782,785,787,789,791,793],{"class":343,"line":771},16,[341,773,397],{"class":366},[341,775,400],{"class":358},[341,777,403],{"class":358},[341,779,406],{"class":358},[341,781,727],{"class":358},[341,783,784],{"class":358}," json",[341,786,571],{"class":570},[341,788,574],{"class":358},[341,790,577],{"class":362},[341,792,580],{"class":570},[341,794,795],{"class":347},"         # Mind Elixir JSON\n",[341,797,799,801,803,805,807,809,811,813,815,817,819,822],{"class":343,"line":798},17,[341,800,397],{"class":366},[341,802,400],{"class":358},[341,804,403],{"class":358},[341,806,406],{"class":358},[341,808,727],{"class":358},[341,810,784],{"class":358},[341,812,571],{"class":570},[341,814,574],{"class":358},[341,816,577],{"class":362},[341,818,580],{"class":570},[341,820,821],{"class":354}," --raw",[341,823,824],{"class":347},"   # plain JSON for piping\n",[341,826,828,830,832,834,836,838,841,843,845,847,849],{"class":343,"line":827},18,[341,829,397],{"class":366},[341,831,400],{"class":358},[341,833,403],{"class":358},[341,835,406],{"class":358},[341,837,727],{"class":358},[341,839,840],{"class":358}," stats",[341,842,571],{"class":570},[341,844,574],{"class":358},[341,846,577],{"class":362},[341,848,580],{"class":570},[341,850,851],{"class":347},"        # quick numbers\n",[341,853,855,857,859,861,863,865,868,870,872,874,876],{"class":343,"line":854},19,[341,856,397],{"class":366},[341,858,400],{"class":358},[341,860,403],{"class":358},[341,862,406],{"class":358},[341,864,727],{"class":358},[341,866,867],{"class":358}," pillars-json",[341,869,571],{"class":570},[341,871,574],{"class":358},[341,873,577],{"class":362},[341,875,580],{"class":570},[341,877,878],{"class":347}," # raw content pillar input\n",[341,880,882],{"class":343,"line":881},20,[341,883,377],{"emptyLinePlaceholder":376},[341,885,887],{"class":343,"line":886},21,[341,888,889],{"class":347},"# Flashcard evals\n",[341,891,893,895,897,899,901,904,906,908,910,912],{"class":343,"line":892},22,[341,894,397],{"class":366},[341,896,400],{"class":358},[341,898,403],{"class":358},[341,900,406],{"class":358},[341,902,903],{"class":358}," evaluate-flashcards",[341,905,571],{"class":570},[341,907,574],{"class":358},[341,909,577],{"class":362},[341,911,580],{"class":570},[341,913,914],{"class":347},"  # run flashcard evals on a deck\n",[341,916,918,920,922,924,926,928,930,932,934,936,939],{"class":343,"line":917},23,[341,919,397],{"class":366},[341,921,400],{"class":358},[341,923,403],{"class":358},[341,925,406],{"class":358},[341,927,903],{"class":358},[341,929,571],{"class":570},[341,931,574],{"class":358},[341,933,577],{"class":362},[341,935,580],{"class":570},[341,937,938],{"class":354}," --metrics",[341,940,941],{"class":358}," blueprint_coverage,relevance\n",[341,943,945,947,949,951,953,955,957,959,961,963,966],{"class":343,"line":944},24,[341,946,397],{"class":366},[341,948,400],{"class":358},[341,950,403],{"class":358},[341,952,406],{"class":358},[341,954,903],{"class":358},[341,956,571],{"class":570},[341,958,574],{"class":358},[341,960,577],{"class":362},[341,962,580],{"class":570},[341,964,965],{"class":354}," --json",[341,967,968],{"class":347},"   # raw JSON for piping\n",[293,970,971,972,975,976,979,980,983,984,987,988,991],{},"The ",[309,973,974],{},"evaluate-flashcards"," flow: ",[309,977,978],{},"POST \u002Fevaluate\u002Fdeck"," with the chosen metrics, then poll ",[309,981,982],{},"GET \u002Fruns\u002F\u003Crun_id>"," until done. Default metrics are ",[309,985,986],{},"blueprint_coverage,relevance,redundancy,independence"," (leakage off by default — opt in via ",[309,989,990],{},"--metrics",").",[993,994,996],"h3",{"id":995},"adding-a-new-deck-from-a-file","Adding a new deck from a file",[293,998,999,1000,1003],{},"To parse a local PDF and create a new deck, use the ",[309,1001,1002],{},"ingest"," command. This uploads the file to the playground server, triggers the full ingestion pipeline (parsing, chunking, content pillar generation), and waits for it to finish.",[302,1005,1007],{"className":335,"code":1006,"language":337,"meta":311,"style":311},"# Parse a PDF and wait for the deck to be ready (default)\nuv run python cli.py ingest \u002Fpath\u002Fto\u002Ffile.pdf\n\n# Custom deck name (defaults to filename)\nuv run python cli.py ingest \u002Fpath\u002Fto\u002Ffile.pdf --name \"My Deck\"\n\n# Start ingestion without waiting\nuv run python cli.py ingest \u002Fpath\u002Fto\u002Ffile.pdf --no-wait\n\n# Check on a deck's ingestion status \u002F wait for it to finish\nuv run python cli.py wait \u003Cdeck_id>\n\n# Wait for all pending decks at once\nuv run python cli.py wait\n",[309,1008,1009,1014,1030,1034,1039,1060,1064,1069,1086,1090,1095,1117,1121,1126],{"__ignoreMap":311},[341,1010,1011],{"class":343,"line":344},[341,1012,1013],{"class":347},"# Parse a PDF and wait for the deck to be ready (default)\n",[341,1015,1016,1018,1020,1022,1024,1027],{"class":343,"line":351},[341,1017,397],{"class":366},[341,1019,400],{"class":358},[341,1021,403],{"class":358},[341,1023,406],{"class":358},[341,1025,1026],{"class":358}," ingest",[341,1028,1029],{"class":358}," \u002Fpath\u002Fto\u002Ffile.pdf\n",[341,1031,1032],{"class":343,"line":373},[341,1033,377],{"emptyLinePlaceholder":376},[341,1035,1036],{"class":343,"line":380},[341,1037,1038],{"class":347},"# Custom deck name (defaults to filename)\n",[341,1040,1041,1043,1045,1047,1049,1051,1054,1057],{"class":343,"line":386},[341,1042,397],{"class":366},[341,1044,400],{"class":358},[341,1046,403],{"class":358},[341,1048,406],{"class":358},[341,1050,1026],{"class":358},[341,1052,1053],{"class":358}," \u002Fpath\u002Fto\u002Ffile.pdf",[341,1055,1056],{"class":354}," --name",[341,1058,1059],{"class":358}," \"My Deck\"\n",[341,1061,1062],{"class":343,"line":394},[341,1063,377],{"emptyLinePlaceholder":376},[341,1065,1066],{"class":343,"line":586},[341,1067,1068],{"class":347},"# Start ingestion without waiting\n",[341,1070,1071,1073,1075,1077,1079,1081,1083],{"class":343,"line":611},[341,1072,397],{"class":366},[341,1074,400],{"class":358},[341,1076,403],{"class":358},[341,1078,406],{"class":358},[341,1080,1026],{"class":358},[341,1082,1053],{"class":358},[341,1084,1085],{"class":354}," --no-wait\n",[341,1087,1088],{"class":343,"line":636},[341,1089,377],{"emptyLinePlaceholder":376},[341,1091,1092],{"class":343,"line":663},[341,1093,1094],{"class":347},"# Check on a deck's ingestion status \u002F wait for it to finish\n",[341,1096,1097,1099,1101,1103,1105,1108,1110,1112,1114],{"class":343,"line":688},[341,1098,397],{"class":366},[341,1100,400],{"class":358},[341,1102,403],{"class":358},[341,1104,406],{"class":358},[341,1106,1107],{"class":358}," wait",[341,1109,571],{"class":570},[341,1111,574],{"class":358},[341,1113,577],{"class":362},[341,1115,1116],{"class":570},">\n",[341,1118,1119],{"class":343,"line":705},[341,1120,377],{"emptyLinePlaceholder":376},[341,1122,1123],{"class":343,"line":710},[341,1124,1125],{"class":347},"# Wait for all pending decks at once\n",[341,1127,1128,1130,1132,1134,1136],{"class":343,"line":716},[341,1129,397],{"class":366},[341,1131,400],{"class":358},[341,1133,403],{"class":358},[341,1135,406],{"class":358},[341,1137,1138],{"class":358}," wait\n",[293,1140,1141,1142,458,1145,1148,1149,1152,1153,487],{},"Once ingestion completes, inspect the deck with ",[309,1143,1144],{},"pillars",[309,1146,1147],{},"chunks",", or ",[309,1150,1151],{},"mindmap",", and score the cards with ",[309,1154,974],{},[297,1156,1158],{"id":1157},"key-files","Key files",[1160,1161,1162,1175],"table",{},[1163,1164,1165],"thead",{},[1166,1167,1168,1172],"tr",{},[1169,1170,1171],"th",{},"File",[1169,1173,1174],{},"Purpose",[1176,1177,1178,1189,1201,1225,1242,1258,1268,1281,1291,1301,1311,1321,1331],"tbody",{},[1166,1179,1180,1186],{},[1181,1182,1183],"td",{},[309,1184,1185],{},"evals-playground\u002Fapp.py",[1181,1187,1188],{},"FastAPI server — the canonical API. All reads\u002Fwrites against Supabase, all task dispatch.",[1166,1190,1191,1196],{},[1181,1192,1193],{},[309,1194,1195],{},"evals-playground\u002Fapi_models.py",[1181,1197,1198,1199,487],{},"Pydantic request\u002Fresponse schemas for ",[309,1200,316],{},[1166,1202,1203,1208],{},[1181,1204,1205],{},[309,1206,1207],{},"evals-playground\u002Fsdk.py",[1181,1209,1210,1211,1213,1214,458,1217,1220,1221,1224],{},"In-process orchestration called from ",[309,1212,316],{},": ",[309,1215,1216],{},"evaluate()",[309,1218,1219],{},"evaluate_quiz()",", per-metric wrappers, ",[309,1222,1223],{},"MetricName"," registry, composite weights.",[1166,1226,1227,1232],{},[1181,1228,1229],{},[309,1230,1231],{},"evals-playground\u002Feval_runner.py",[1181,1233,1234,1235,1238,1239,1241],{},"Background runner glue; ",[309,1236,1237],{},"METRIC_FNS"," registry that ",[309,1240,316],{}," dispatches against.",[1166,1243,1244,1249],{},[1181,1245,1246],{},[309,1247,1248],{},"evals-playground\u002Fmetrics\u002F",[1181,1250,1251,1252,1254,1255,487],{},"Pure metric implementations (one file per metric). Add new metrics here, then register in ",[309,1253,461],{}," + ",[309,1256,1257],{},"eval_runner.METRIC_FNS",[1166,1259,1260,1265],{},[1181,1261,1262],{},[309,1263,1264],{},"evals-playground\u002Fcli.py",[1181,1266,1267],{},"CLI client over the REST API. Commands map 1:1 to endpoints.",[1166,1269,1270,1275],{},[1181,1271,1272],{},[309,1273,1274],{},"evals-playground\u002Fdb.py",[1181,1276,1277,1278,1280],{},"Supabase queries — imported by ",[309,1279,316],{}," only; CLI does not touch this.",[1166,1282,1283,1288],{},[1181,1284,1285],{},[309,1286,1287],{},"evals-playground\u002Ffrontend\u002Fsrc\u002Flib\u002Fapi.ts",[1181,1289,1290],{},"Frontend API client (mirror of the CLI's HTTP calls).",[1166,1292,1293,1298],{},[1181,1294,1295],{},[309,1296,1297],{},"evals-playground\u002Ffrontend\u002Fsrc\u002Fcomponents\u002FPillarsView.tsx",[1181,1299,1300],{},"Web pillars viewer (with excluded chunks panel).",[1166,1302,1303,1308],{},[1181,1304,1305],{},[309,1306,1307],{},"evals-playground\u002Ffrontend\u002Fsrc\u002Fcomponents\u002FMindmapView.tsx",[1181,1309,1310],{},"Web mindmap viewer.",[1166,1312,1313,1318],{},[1181,1314,1315],{},[309,1316,1317],{},"workers\u002Flearning_agents\u002Fmindmap_agent\u002Fmindmap_generator.py",[1181,1319,1320],{},"Production mindmap agent.",[1166,1322,1323,1328],{},[1181,1324,1325],{},[309,1326,1327],{},"workers\u002Flearning_agents\u002Futil\u002Fcontent_pillar_structure.py",[1181,1329,1330],{},"Pure content pillar ops (formatting, exclusion, models).",[1166,1332,1333,1338],{},[1181,1334,1335],{},[309,1336,1337],{},"shared\u002Fsrc\u002Fshared\u002Fschemas\u002Fcontent_pillar.py",[1181,1339,1340],{},"Content pillar Pydantic schema.",[297,1342,1344],{"id":1343},"qualitative-review-protocol","Qualitative review protocol",[293,1346,1347],{},"You and the user iterate together on AI generation quality. You are a co-developer, not a judge — you spot issues, simulate a student, suggest improvements, and bring evidence. The user gives direction. You never give final verdicts.",[993,1349,1351],{"id":1350},"two-lenses","Two lenses",[293,1353,1354],{},"Every review looks through two lenses:",[433,1356,1357,1363],{},[436,1358,1359,1362],{},[439,1360,1361],{},"Student lens",": Simulate a learner studying this material. What's useful for exam prep? What key takeaways are missing? What's noise that would waste study time? Would a student find the right section when they need it? Be specific — reference concrete items (\"subtopic 'General Background Principles' is too vague — a student wouldn't know what's in there\").",[436,1364,1365,1368],{},[439,1366,1367],{},"Context engineering lens",": Is the LLM getting the right amount of signal in its prompt\u002Finput? Too much wastes tokens and confuses. Too little loses important info. When output is bad, trace backwards: was the prompt clear? Did the LLM have enough context? Or too much noise? For example: \"the structure LLM only sees 60 chars per chunk — is that enough to distinguish 'References to Classical Literature' (educational) from 'References' (bibliography)?\"",[993,1370,1372],{"id":1371},"layered-inspection","Layered inspection",[293,1374,1375],{},"Be smart about token usage. Don't dump everything into context at once. Go deeper only when something smells off:",[433,1377,1378,1384,1390,1396],{},[436,1379,1380,1383],{},[439,1381,1382],{},"Start with the output"," (mindmap tree, flashcard list, pillar structure) — scan for obvious issues",[436,1385,1386,1389],{},[439,1387,1388],{},"Spot-check against pillars"," — if a topic looks wrong, check what the pillar says",[436,1391,1392,1395],{},[439,1393,1394],{},"Dig into chunks"," — if the pillar looks off, check raw docling chunks",[436,1397,1398,1401],{},[439,1399,1400],{},"Read the PDF"," — only if chunks seem wrong or missing (layout issues, missing text)",[993,1403,1405],{"id":1404},"bring-receipts","Bring receipts",[293,1407,1408],{},"Never make claims without evidence. If you say \"this topic is missing key content,\" show which chunk has that content and where it went. If you say \"the exclusion is wrong,\" show the chunk text. Use CLI commands to pull data and quote it.",[293,1410,1411,1412,1415],{},"Help the user inspect things in the ",[439,1413,1414],{},"web playground"," too — if something would be clearer with a visual (bounding boxes on the PDF, excluded chunks highlighted, side-by-side comparison), say so and suggest what the web view should show.",[993,1417,1419],{"id":1418},"request-better-tooling","Request better tooling",[293,1421,1422],{},"If you're struggling to inspect something or the CLI doesn't support what you need, the answer is to extend it (see \"Extending the playground\" above), not to work around it. Tell the user explicitly: \"I need a CLI\u002FREST capability that does X — right now I can't easily check Y. I'll add the endpoint + command unless you'd rather scope it differently.\" Add the metric\u002Fquery\u002Fetc., expose via REST, wrap with CLI. The CLI was built for you; growing it is part of the work.",[993,1424,1426],{"id":1425},"evals","Evals",[293,1428,1429],{},"When reviewing outputs, regularly consider: would an eval catch this? Suggest adding an eval when a pattern recurs or when an existing eval misses a problem. Evals are discovered through the work, not predefined — but once discovered, they should be validated against real cases to confirm they actually capture the issue.",[297,1431,1433],{"id":1432},"debugging-parsing-issues","Debugging parsing issues",[293,1435,1436,1437,1440],{},"When chunks look wrong (missing text, wrong order, merged content), ",[439,1438,1439],{},"always look at the actual PDF first"," before theorizing. Use the Read tool on the PDF file to visually inspect the layout, or download it from Supabase storage:",[302,1442,1446],{"className":1443,"code":1444,"language":1445,"meta":311,"style":311},"language-python shiki shiki-themes github-light github-dark","# Find and download the PDF\nclient = get_supabase_client()\nfiles = client.storage.from_('PDF').list(f'{user_id}\u002F')\n# Then curl the public URL to \u002Ftmp\u002F and Read it\n","python",[309,1447,1448,1453,1458,1463],{"__ignoreMap":311},[341,1449,1450],{"class":343,"line":344},[341,1451,1452],{},"# Find and download the PDF\n",[341,1454,1455],{"class":343,"line":351},[341,1456,1457],{},"client = get_supabase_client()\n",[341,1459,1460],{"class":343,"line":373},[341,1461,1462],{},"files = client.storage.from_('PDF').list(f'{user_id}\u002F')\n",[341,1464,1465],{"class":343,"line":380},[341,1466,1467],{},"# Then curl the public URL to \u002Ftmp\u002F and Read it\n",[293,1469,1470],{},"Then compare what you see in the PDF against:",[433,1472,1473,1488,1495],{},[436,1474,1475,1476,1479,1480,1483,1484,1487],{},"The docling JSON (",[309,1477,1478],{},"docling_json_url",") — check reading order via ",[309,1481,1482],{},"texts[]"," items and their ",[309,1485,1486],{},"prov[].bbox"," y-coordinates",[436,1489,1490,1491,1494],{},"The markdown (",[309,1492,1493],{},"md_url",") — check if content exists but is misordered",[436,1496,1497,1498,1501],{},"The docling chunks (",[309,1499,1500],{},"docling_chunks_url",") — check what the chunker produced",[293,1503,1504,1505,1508],{},"Check ",[309,1506,1507],{},"evals-playground\u002Fknown-issues\u002F"," for documented cases with PDFs and evidence. When you discover a new issue, add it there following the same format (markdown + PDF).",[297,1510,1512],{"id":1511},"cross-checking-workflow-metrics-with-subagents","Cross-checking workflow metrics with subagents",[293,1514,1515,1516,1519,1520,1523],{},"Quiz\u002Fflashcard LLM metrics run as ",[439,1517,1518],{},"workflow"," judges (Gemini with structured output, cheap, consistent). For trust-critical decisions, cross-check with a Claude Code subagent (",[439,1521,1522],{},"agent"," judge) that reads the full bundle and writes its own JSON verdict.",[293,1525,1526,1529,1530,1533,1534,1537,1538,1540],{},[439,1527,1528],{},"Step 0 — read the rubric."," Before doing anything, read ",[309,1531,1532],{},"apps\u002Flearning-api\u002Fevals-playground\u002Fmetrics\u002FREADME.md"," to see what each metric is supposed to measure. The rubric lives in three places (the doc, the workflow prompt in the metric's ",[309,1535,1536],{},".py",", the bundle prep in ",[309,1539,486],{},") and they must match. If they've drifted, align all three before the agreement numbers mean anything.",[293,1542,1543,1546,1547,1550,1551,1554,1555,1558,1559,1562],{},[439,1544,1545],{},"Workflow:"," CLI ",[309,1548,1549],{},"prepare-\u003Cmetric>-review \u003Cdeck>"," writes a self-contained bundle.md. Spawn an ",[309,1552,1553],{},"Agent"," to produce a JSON report. CLI ",[309,1556,1557],{},"cross-check-\u003Cmetric> \u003Cdeck>"," diffs agent vs workflow. Use ",[309,1560,1561],{},"cli.py --help"," for current command names.",[293,1564,1565],{},[439,1566,1567],{},"Agent config:",[450,1569,1570,1578,1581],{},[436,1571,1572,458,1575,487],{},[309,1573,1574],{},"subagent_type: \"general-purpose\"",[309,1576,1577],{},"model: \"opus\"",[436,1579,1580],{},"Prompt points at the bundle; agent writes JSON to the path in the bundle's Output contract.",[436,1582,1583],{},"Read the bundle fully, never fall back to general knowledge, no prose beyond \"wrote report to X\".",[293,1585,1586,1589,1590,1593],{},[439,1587,1588],{},"Binary beats 3-way for subjective metrics."," If the middle class is a judgment call, collapse to binary (see ",[309,1591,1592],{},"metrics\u002FREADME.md"," for which metrics are binary). With a squishy middle class the agent-vs-agent ceiling is ~70%, which makes any >70% target impossible.",[293,1595,1596,1599],{},[439,1597,1598],{},"Two-run consensus."," Run the agent twice, different output paths. Agent-vs-agent agreement = noise floor. Workflow is trustworthy if it agrees with the consensus subset (items both agents agreed on) at ≥70%. If agent-vs-agent is under ~85%, fix the rubric before blaming workflow.",[293,1601,1602,1605],{},[439,1603,1604],{},"Verify agent quotes."," If an agent verdict flips a workflow call, grep the quoted passage against the bundle. Fabricated quotes = agent failure mode; retry with a stricter prompt.",[297,1607,1609],{"id":1608},"principles","Principles",[450,1611,1612,1618,1624,1633,1639,1645],{},[436,1613,1614,1617],{},[439,1615,1616],{},"LLM output should be simple",": Have the model output a plain tree. All rendering-library-specific formatting happens in code.",[436,1619,1620,1623],{},[439,1621,1622],{},"No fallback logic",": If something fails, raise an error. Don't silently degrade.",[436,1625,1626,1629,1630,1632],{},[439,1627,1628],{},"CLI and web app must stay in sync",": Both consume the same backend via ",[309,1631,316],{}," over HTTP. Don't build separate logic paths or let the CLI fall back to direct Supabase access.",[436,1634,1635,1638],{},[439,1636,1637],{},"Read before editing",": Always read the current file state before modifying — structures evolve.",[436,1640,1641,1644],{},[439,1642,1643],{},"Never over-fit to one example",": If a change makes one document look great but would break others, it's a bad change. Test on multiple decks when possible.",[436,1646,1647,1650],{},[439,1648,1649],{},"Show first, then discuss",": Before and after any change, show a digestible summary of the output. Pick the right format — tree, table, diff, bullet points.",[1652,1653,1654],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}",{"title":311,"searchDepth":351,"depth":351,"links":1656},[1657,1658,1659,1660,1663,1664,1671,1672,1673],{"id":299,"depth":351,"text":300},{"id":320,"depth":351,"text":321},{"id":427,"depth":351,"text":428},{"id":490,"depth":351,"text":491,"children":1661},[1662],{"id":995,"depth":373,"text":996},{"id":1157,"depth":351,"text":1158},{"id":1343,"depth":351,"text":1344,"children":1665},[1666,1667,1668,1669,1670],{"id":1350,"depth":373,"text":1351},{"id":1371,"depth":373,"text":1372},{"id":1404,"depth":373,"text":1405},{"id":1418,"depth":373,"text":1419},{"id":1425,"depth":373,"text":1426},{"id":1432,"depth":351,"text":1433},{"id":1511,"depth":351,"text":1512},{"id":1608,"depth":351,"text":1609},"Use this skill when working on AI generation features (mindmaps, flashcards, quizzes, summaries, podcasts) that need iteration in the eval playground. Provides CLI commands to inspect decks, content pillars, and generation outputs, and guidance on how to co-develop with the user.","md",null,{"name":1678,"allowed-tools":1679},"eval-playground","Bash Read Edit Write Grep Glob",{"title":60,"description":1674},".claude\u002Fskills\u002Feval-playground\u002FSKILL","945VyxnByHIe_nIDA0WJDZw_L1aXN231FUnXFo9NC2s",1779007962947]