Thanks for helping to improve LearnKit.
This document covers two common contribution paths:
- translating the plugin into new languages
- updating the Companion model compatibility table with tested provider and model results
The Companion compatibility page is community-maintained and should reflect confirmed behavior in real LearnKit use.
Edit site/src/content/docs/Companion-Model-Compatibility.md when:
- you test a provider or model that is not listed yet
- a listed model changes behavior after a LearnKit update or provider-side change
- you confirm an important caveat that should help users choose a model, especially around attachments or intermittent failures
If the result looks like a product bug rather than a simple compatibility note, also file the Companion AI issue report so it can be tracked separately.
- Edit
site/src/content/docs/Companion-Model-Compatibility.md. - Add a new row or update an existing row for the exact provider and model ID you tested.
- Mark each feature with
✅,❌, orVariesif the provider route is not stable. - Keep the comment short but specific. Note the main caveat, such as attachment limits, image support, or repeatable API errors.
- Open a pull request that includes the LearnKit version, provider, exact model ID, tested features, and any attachment types you tried.
- Chat — ask Companion to review or explain the active note and confirm it returns a normal chat response.
- Edit — ask Companion to make a concrete change and confirm the proposed edit can be applied back into the note.
- Generate Flashcards — generate flashcards from a note and confirm the drafted cards appear and can be inserted.
- Generate Tests — generate a short test, complete it, and confirm grading works as expected.
- File Attachments — if supported by your setup, test a note with embedded or linked attachments and record what file types worked.
We welcome translation contributions! Whether you want to add a brand-new language or improve an existing one, PRs are the best way to contribute.
| Code | Language | Status |
|---|---|---|
en-gb |
English (UK) | ✅ Stable — baseline |
en-us |
English (US) | ✅ Stable — override only |
zh-cn |
Chinese (Simplified) | ✅ Community — complete |
fr |
French | 🚧 Community — needs translation |
ja |
Japanese | 🚧 Community — needs translation |
es |
Spanish | 🚧 Community — needs translation |
hi |
Hindi | 🚧 Community — needs translation |
Ways to contribute:
- Add a new language — copy
en-base.json, translate the values, and open a PR - Improve an existing translation — edit the locale JSON file and open a PR with just the changed keys
- Fix a mistranslation — open an issue or PR with the corrected text
UI strings are wrapped with t(locale, "token.key", "English fallback"). At build time, JSON locale files from src/platform/translations/locales/ are bundled into the plugin. If a token is missing from a locale file the English fallback is used automatically, so partial translations work fine.
en-base.json— the canonical English source containing every translatable key. This is the file you copy when starting a new translation.en-gb.json/en-us.json— small override files that only contain keys that differ from the base (e.g. colour → color). They merge on top ofen-base.jsonat runtime.- Full locale files (
zh-cn.json,fr.json,ja.json,es.json,hi.json) — standalone translation files that contain every key. They are loaded directly without merging over the English base. ui.common.*keys are reusable microcopy tokens for high-frequency labels (Answer, Question, Next, Reset, etc.). Translate these once; they are shared across the UI.
- Copy
src/platform/translations/locales/en-base.jsonto a new file named with the IETF language tag, for examplezh-cn.json. - Translate values only. Do not rename or remove token keys.
- Keep placeholders exactly as-is (e.g.
{count},{language}). - Open a pull request with:
- the new JSON file only (do not edit
locale-registry.tsortranslator.ts) - target language and region (e.g.
zh-CNvszh-TW) - whether this is a new translation or an improvement to an existing one
- any terms that need glossary discussion
- the new JSON file only (do not edit
- A reviewer (a second native or proficient speaker) comments on the PR with feedback. Address any suggestions and push updates until approved.
The reviewer checks for:
- natural, concise wording (not overly literal)
- consistent punctuation and capitalisation with other locales
- correct preservation of placeholder tokens
- faithful meaning for flashcard, scheduling, and review terminology
After review approval the maintainer:
- Adds the locale entry to the registry in
src/platform/translations/locale-registry.ts. - Imports the new JSON file in
src/platform/translations/translator.tsand adds it to theMESSAGE_BUNDLESmap. - Runs lint, tests, and build to verify.
- Merges the PR.
- Prefer natural, concise wording over literal translation.
- Keep punctuation and capitalisation consistent with other locales.
- Avoid product-specific slang unless present in the source English.
- Preserve the semantic meaning of flashcard, review, and scheduling terms.
- One locale per PR when possible.
- Use follow-up PRs for terminology refinements.
- For minor corrections to an existing locale, open a focused PR with just the changed keys.
Open an issue and include:
- locale code
- token key(s)
- current text vs proposed text
- context or screenshot (if useful)