This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
# Build (fts5 tag required for SQLite full-text search)
make build
# Run tests
make test
# Run a single test package
go test -tags "fts5" ./internal/config/...
# Run a single test by name
go test -tags "fts5" -run TestFunctionName ./internal/config/...
# Install to ~/.local/bin
make install
# Install to custom prefix
make install PREFIX=/usr/localImportant: Always include
-tags "fts5"when runninggo buildorgo testdirectly. The Makefile handles this automatically.
The entry point is cmd/voc/main.go, which wires a Cobra CLI with subcommands (search, quiz, convo, list, install-dict). Running voc with no arguments launches the interactive splash screen TUI, which is a loop that delegates back into the same subcommand handlers.
internal/app/app.go is the central dependency container passed to all UI components. It holds:
DB— the user's personal vocabulary (SQLite viago-sqlite3)Dict— the read-only dictionary (separate SQLite, FTS5-indexed, sourced from kaikki.org)HostLang/TargetLang— resolved at startupSettings— config loaded from file + env
| Package | Role |
|---|---|
internal/app |
Creates and owns all shared dependencies; provides GetLLMClient() |
internal/config |
Loads/saves settings.yaml; config precedence: defaults → file → env vars → CLI flags |
internal/database |
User vocabulary SQLite DB (words, word_types, definitions tables + schema migrations); also reads/writes progress.md |
internal/dictionary |
Read-only dictionary SQLite (FTS5 words_fts table with LIKE fallback); installed per target language as dictionary_{lang}.db |
internal/llm |
Google Vertex AI (Gemini) client — GenerateQuiz, Chat, UpdateProgress |
internal/i18n |
Static string maps per locale (en, fr, cs, sk, es, de, pt, pt-br); T(StringID) for lookups; SetHostLanguage / SetTargetLanguage set package-level globals |
internal/ui |
Bubble Tea TUI models: splash, fuzzy (search), quiz, convo |
config.Load()reads~/.config/voc/settings.yaml, then overrides withVOC_HOST_LANG/VOC_TARGET_LANGenv vars, then CLI flags.- The dictionary DB path resolves as:
VOC_DB_PATHenv →DefaultDictionaryDirectorybuild var (set bymake) →~/.config/voc/dictionary_{lang}.db. - The user DB path resolves as:
VOC_USER_DB_PATHenv →DefaultUserDBPathbuild var →~/.local/share/voc/voc.db. - Both
DefaultDictionaryDirectoryandDefaultUserDBPathare injected at build time via-ldflagsin the Makefile.
Add a new map[StringID]string in internal/i18n/i18n.go covering every StringID constant, then register it in the locales map and GetLanguageName.
All Lipgloss styles are defined in internal/ui/styles.go. Use these when building or modifying UI components rather than defining styles inline.
internal/llm wraps cloud.google.com/go/vertexai/genai. Requires env vars VERTEX_API_KEY (or GEMINI_API_KEY) and VERTEX_PROJECT_ID. Default model is gemini-2.5-flash-lite. All LLM responses are JSON; sanitizeJSON strips markdown code fences before unmarshalling.