From kotoba
Generate complete, importable Anki decks (.apkg) for language learning from a plain description of what the user wants to learn. Plans the deck conversationally, generates vocabulary cards with native-script word, reading (ruby), definition, example sentence, translation, TTS audio, and an optional image, then validates and packages everything into a standalone .apkg file. Scales to thousand-card decks via multi-session project mode with a resumable state note. Use this skill whenever the user mentions Anki, flashcards, .apkg, spaced repetition decks, vocab decks, HSK/JLPT/TOPIK prep cards, asks to "make me cards" for any language, or wants to continue/resume an existing deck project or generate the next batch — even if they don't say "Anki" explicitly. Deep support for Mandarin Chinese and Japanese; works for any language pair.
How this skill is triggered — by the user, by Claude, or both
Slash command
/kotoba:kotobaThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Turn "make me 100 HSK4 travel words" into a polished, importable `.apkg` deck. The pipeline: **plan → preview → generate → validate → package**. Each phase exists for a reason — skipping one is how bad cards reach a user's collection.
Turn "make me 100 HSK4 travel words" into a polished, importable .apkg deck. The pipeline: plan → preview → generate → validate → package. Each phase exists for a reason — skipping one is how bad cards reach a user's collection.
Language learning only: vocabulary cards for any L1 → L2 pair. If the user asks for a non-language deck (history, medicine, code), explain this skill is purpose-built for linguistic data and offer to make cards in plain chat instead. High-stakes accuracy domains (medical, legal, certification) are explicitly out of scope.
Sandboxed output is non-negotiable. Always produce a standalone deck the user imports fresh and reviews. Never offer to merge generated cards into an existing deck — one bad batch mixed into a 5,000-card collection destroys trust permanently.
Before generating anything, lock the spec with the user. Ask only what you can't infer:
Then read the matching schema reference — it carries the language-specific generation and validation rules:
references/mandarin.md (deep: pinyin ruby, tone rules, HSK conventions, voices)references/japanese.md (deep: furigana chunking, on/kun reading verification, rendaku, jukujikun, JLPT conventions, counters, voices)references/generic.md (universal schema baseline)No deep reference for the target language? Write one before generating — automatically, without asking. generic.md is a fallback, not a substitute. Every language has reading and naturalness traps that a generic schema can't anticipate (the way Mandarin has dual-pronunciation characters and Japanese has on/kun and rendaku), and those traps are exactly what produces the embarrassing, well-formed-but-wrong cards this pipeline exists to prevent. So the first time a deck is requested in a language without its own references/<language>.md, treat creating that reference as the opening step of Phase 1, not optional polish:
references/mandarin.md and references/japanese.md as models — match their depth, structure, and tone. They are the quality bar.word), the reading/transliteration system and its ambiguities, register and politeness defaults for example sentences, gender/aspect/counter or other per-word grammar worth a field, the level system learners expect (CEFR, TOPIK, etc.), corpus-frequency ordering, and the right edge-tts voices (edge-tts --list-voices). Use web search and your own knowledge; cross-check anything you're unsure of.references/<language>.md covering: field population (word/word_ruby/reading/sentence/sentence_ruby), the #1 reading-hallucination class for this language with concrete examples, example-sentence discipline, level/tag/ordering conventions, grammatical extras worth a field, voices, validation specifics (what validate.py can and can't catch), and a common-pitfalls checklist. Mirror the existing deep references section-for-section.This is automatic and silent — don't ask the user whether to create the reference, just do it as part of getting their deck right. Mention it in a sentence once done ("I wrote a Korean reference for the skill first, then built your deck") so they know it now exists for next time.
If the skill's own references/ directory is read-only (it often is when installed), write the new reference to a working copy in the session workspace and read it from there for this deck. Then tell the user the reference exists only for this session, and that to make it permanent for future decks they should repackage the skill with the new file (or ask you to) and reinstall — the same way Japanese was added.
Also read references/deck-json.md — the exact contract for the deck.json file that the build script consumes.
Decks beyond ~200 cards are multi-session projects. Read references/large-decks.md and switch to project mode: curate a complete wordlist first, then generate in batches across sessions with a state note tracking progress. Also read it whenever the user says "continue my deck", "next batch", or references an existing deck project — find their state note and resume from it.
Write a deck.json containing only ~5 representative cards, then render it:
python scripts/build_deck.py deck.json --preview preview.html
Show the user the preview (it renders front and back with the real template and CSS — what they approve is exactly what gets packaged). Iterate on fields, styling, sentence difficulty, or anything else until the user explicitly approves. Do not start bulk generation before approval; regenerating 300 cards because the template was wrong wastes everyone's time and money.
The card layout (Kaishi 1.5k style):
Generate card data into deck.json in batches of 25–50 cards per pass. Quality rules that matter more than speed:
deck.json is the order Anki shows new cards.Two tiers, both required:
python scripts/validate.py deck.json. Catches structural errors: missing fields, duplicates, sentence not containing the target word, malformed ruby, invalid pinyin syllables (Mandarin). Fix every reported error before proceeding.python scripts/build_deck.py deck.json --out "Deck Name.apkg"
The script generates TTS audio (edge-tts), fetches CC-licensed images for cards with an image_query (Openverse, attribution written to a sidecar *-image-credits.txt), and packages everything with genanki. Flags: --no-audio, --no-images for graceful degradation when the network is unavailable — tell the user what was skipped rather than failing silently.
Deliver the .apkg with one-line import instructions (Anki → File → Import; works on desktop, AnkiMobile, AnkiDroid). Remind the user to skim the deck in the browser before studying — it's a fresh standalone deck precisely so they can review it cheaply.
pip install genanki edge-tts (use --break-system-packages if the environment requires it). Audio and images need network access; everything else runs offline.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub yufengliu15/kotoba --plugin kotoba