soju (unified entry)¶
Single console entry for all Soju CLI tools. Install with uv sync, then run
uv run soju <subcommand> ….
Global options (before the subcommand): --language / -L, --verbose.
soju¶
Usage: soju [OPTIONS] COMMAND [ARGS]...
Soju Korean language learning platform CLI.
╭─ Options ──────────────────────────────────────────────────────────────────╮
│ --language -L <str> Target language plugin code (default: │
│ $SOJU_LANGUAGE or ko) │
│ --verbose Enable verbose logging │
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────╮
│ promote Promote local topic entries to registry. │
│ align Validate verb forms and examples against table layout. │
│ registry Validate vocabulary registry, types, topic refs, and │
│ grammar levels. │
│ validate-schemas Run check-jsonschema over all canonical data files. │
│ fill-verbs Generate verb forms and examples for registry verbs. │
│ fill-examples Generate noun and verb example sentences via Ollama. │
│ translate-words Translate a plain-text word list into soju import JSON │
│ via Ollama. │
│ embed-index Build the Ollama embedding cache for Practice retrieval │
│ (data/cache/embeddings/). │
│ backend Run the Soju FastAPI backend (LLM + TTS │
│ OpenAI-compatible API). │
│ import Import vocabulary into Soju data files. │
│ levels List and assign vocabulary and grammar course levels. │
╰────────────────────────────────────────────────────────────────────────────╯
promote¶
Usage: soju promote [OPTIONS]
Promote local topic entries to registry.
╭─ Options ──────────────────────────────────────────────────────────────────╮
│ * --topic <str> Topic id (e.g. family) │
│ [required] │
│ --dry-run │
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────╯
align¶
Usage: soju align [OPTIONS]
Validate verb forms and examples against table layout.
╭─ Options ──────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────╯
registry¶
Usage: soju registry [OPTIONS]
Validate vocabulary registry, types, topic refs, and grammar levels.
╭─ Options ──────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────╯
validate-schemas¶
Usage: soju validate-schemas [OPTIONS]
Run check-jsonschema over all canonical data files.
╭─ Options ──────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────╯
fill-verbs¶
Usage: soju fill-verbs [OPTIONS]
Generate verb forms and examples for registry verbs.
╭─ Options ──────────────────────────────────────────────────────────────────╮
│ --dry-run │
│ --fill-empty Only fill missing forms/examples; leave existing │
│ entries unchanged │
│ --strict Exit non-zero when no verbs were updated (useful in │
│ automation) │
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────╯
fill-examples¶
Usage: soju fill-examples [OPTIONS]
Generate noun and verb example sentences via Ollama.
╭─ Options ──────────────────────────────────────────────────────────────────╮
│ --model <str> [default: gemma4:e4b] │
│ --base-url <str> [default: │
│ http://localhost:11434] │
│ --temperature <float> [default: 0.4] │
│ --verb-batch-size <int> Verbs per Ollama request │
│ [default: 4] │
│ --noun-batch-size <int> Nouns per Ollama request │
│ [default: 6] │
│ --verbs-only │
│ --nouns-only │
│ --clean-only Strip (formal)/(casual) │
│ notes from example │
│ English only │
│ --local Generate examples with │
│ local Korean 1A/1B │
│ templates (no Ollama) │
│ --level <str> Course level (default: │
│ SOJU_LANGUAGE_LEVEL or │
│ 1A; see │
│ data/content/levels.yam… │
│ --examples N Example sentences per │
│ verb tense/variant and │
│ per noun (default: 1) │
│ [default: 1] │
│ --max-attempts N Ollama attempts per verb │
│ batch before giving up │
│ (default: 3) │
│ [default: 3] │
│ --mode <fill-empty|refresh-all fill-empty: only entries │
│ > missing examples │
│ (default); refresh-all: │
│ regenerate every entry │
│ [default: fill-empty] │
│ --verbose │
│ --limit <int> Process only the first N │
│ entries (testing) │
│ --dry-run │
│ --strict Exit non-zero when any │
│ generation warnings were │
│ produced │
│ --help Show this message and │
│ exit. │
╰────────────────────────────────────────────────────────────────────────────╯
translate-words¶
Usage: soju translate-words [OPTIONS]
Translate a plain-text word list into soju import JSON via Ollama.
╭─ Options ──────────────────────────────────────────────────────────────────╮
│ * --file -f <path> Plain-text word list file │
│ [required] │
│ --output -o <path> Write JSON to this file instead of │
│ stdout │
│ --model <str> Ollama model name │
│ [default: gemma4:e4b] │
│ --base-url <str> Ollama base URL │
│ [default: http://localhost:11434] │
│ --batch-size <int> Lines per Ollama request │
│ [default: 8] │
│ --temperature <float> Sampling temperature │
│ [default: 0.3] │
│ --skip-existing Omit entries already in the registry │
│ --level <str> Course level (default: │
│ SOJU_LANGUAGE_LEVEL or 1A; see │
│ data/content/levels.yaml) │
│ --dry-run Parse input and print summary without │
│ calling Ollama │
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────╯
embed-index¶
Usage: soju embed-index [OPTIONS]
Build the Ollama embedding cache for Practice retrieval
(data/cache/embeddings/).
╭─ Options ──────────────────────────────────────────────────────────────────╮
│ --base-url <str> Ollama base URL │
│ [default: http://localhost:11434] │
│ --embed-model <str> Ollama embedding model (default: │
│ SOJU_EMBED_MODEL or nomic-embed-text) │
│ [default: nomic-embed-text] │
│ --batch-size <int> Documents per Ollama /api/embed batch request │
│ [default: 32] │
│ --dry-run Count documents to embed without calling │
│ Ollama │
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────╯
backend¶
Usage: soju backend [OPTIONS]
Run the Soju FastAPI backend (LLM + TTS OpenAI-compatible API).
╭─ Options ──────────────────────────────────────────────────────────────────╮
│ --config -c <file> YAML override path (default: │
│ ~/.config/soju/backend.yaml │
│ if present, else packaged │
│ defaults) │
│ --host <str> Bind host (overrides YAML │
│ server.host) │
│ --port <int range> [1<=x<=65535] Bind port (overrides YAML │
│ server.port) │
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────╯
import¶
Usage: soju import [OPTIONS] COMMAND [ARGS]...
Import vocabulary into Soju data files.
╭─ Options ──────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────╮
│ words Import words into a topic. │
│ verbs Import verbs. │
╰────────────────────────────────────────────────────────────────────────────╯
words¶
Usage: soju import words [OPTIONS]
Import words into a topic.
╭─ Options ──────────────────────────────────────────────────────────────────╮
│ * --topic <str> Topic id from topics manifest │
│ [required] │
│ --dry-run │
│ --section <str> Section id within the topic (required if │
│ multiple) │
│ --file <path> Plain-text word list file │
│ --stdin-json Read JSON records from stdin │
│ --from-staging <path> Staging YAML file path │
│ --level <str> Course level id from levels.yaml (omit to │
│ leave new words unassigned; per-record │
│ level wins) │
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────╯
verbs¶
Usage: soju import verbs [OPTIONS]
Import verbs.
╭─ Options ──────────────────────────────────────────────────────────────────╮
│ --dry-run │
│ --file <path> Not supported without --stdin-json │
│ --stdin-json Read JSON records from stdin │
│ --level <str> Course level id from levels.yaml (omit to │
│ leave new words unassigned; per-record level │
│ wins) │
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────╯
levels¶
Usage: soju levels [OPTIONS] COMMAND [ARGS]...
List and assign vocabulary and grammar course levels.
╭─ Options ──────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────╮
│ list-unassigned List entries with no course level tag. │
│ set Assign a course level to selected vocabulary or grammar │
│ entries. │
╰────────────────────────────────────────────────────────────────────────────╯
list-unassigned¶
Usage: soju levels list-unassigned [OPTIONS]
List entries with no course level tag.
╭─ Options ──────────────────────────────────────────────────────────────────╮
│ --format <str> Output format: table (default) or ids │
│ [default: table] │
│ --kind <str> Target kind: vocabulary (default) or grammar │
│ [default: vocabulary] │
│ --type <str> Filter by vocabulary type id (e.g. noun, verb) │
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────╯
set¶
Usage: soju levels set [OPTIONS]
Assign a course level to selected vocabulary or grammar entries.
╭─ Options ──────────────────────────────────────────────────────────────────╮
│ * --level <str> Course level id from levels.yaml │
│ [required] │
│ --kind <str> Target kind: vocabulary (default) or │
│ grammar │
│ [default: vocabulary] │
│ --all-unassigned Assign every unassigned entry of the │
│ chosen kind │
│ --id <str> Vocabulary UUID or grammar pattern id │
│ (repeatable) │
│ --ids-file <path> File of ids (one per line); use - for │
│ stdin │
│ --dry-run │
│ --force Allow overwriting an existing level tag │
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────╯
uv run soju --help
uv run soju import words --topic common --stdin-json --dry-run < records.json
uv run soju promote --topic family --dry-run
uv run soju validate-schemas
uv run soju embed-index --dry-run
See the individual pages under CLI reference for purpose notes and longer examples.