GitHub - MagicLex/languageme: Progressive language-immersion drip for Claude Code: preprompt a % of each reply in a target language, monitor the real ratio, ramp it up as you keep up. · GitHub
/" data-turbo-transient="true" />
Skip to content
Search/
Sign in<br>Sign upAppearance settings
You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
{{ message }}
MagicLex
languageme
Public
Notifications<br>You must be signed in to change notification settings
Fork
Star
main
BranchesTags
Go to file
CodeOpen more actions menu
Latest commit
History<br>19 Commits<br>19 Commits
Folders and files<br>NameNameLast commit message<br>Last commit date<br>assets
assets
.gitignore
.gitignore
LICENSE
LICENSE
README.md
README.md
languageme
languageme
View all files
Repository files navigation
/ˈlæŋɡwə ʒɛm/
A progressive language-immersion drip for Claude Code. It preprompts, forces<br>and monitors how much of each reply comes back in a target language, and ramps<br>that share up on evidence you're keeping up, not on a calendar.
Standalone: one Python file, stdlib only, no pip installs. A blend drip, not<br>a hard language switch.
How it works
Four layers, wired as three Claude Code hooks plus a statusline segment:
Preprompt (SessionStart hook). languageme hook injects the drip into<br>every new session: blend ~N% of your prose into the target, keep the rest in<br>your usual reply language. It states N as a concrete per-paragraph quantum<br>(a model cannot self-calibrate a raw percentage) and tells you to judge each<br>reply against the target, not against your own earlier replies. N lives in<br>state. The target is confined to chat prose, never code, commits, filenames,<br>tool arguments, or any clause where a wrong word breaks something.
Nudge (UserPromptSubmit hook). languageme nudge closes the loop the<br>one-shot preprompt cannot. Before each reply it injects one live line from the<br>previous turn's measured blend: last reply 80% vs ~16% target, well over, one short phrase per paragraph. This re-asserts the target every turn (immune<br>to context growth) and corrects both overshoot and full dropout, the two ways<br>an open-loop drip drifts.
Monitor (Stop hook). languageme monitor reads the finished transcript,<br>measures the real target-language share you produced (char-weighted,<br>per-token classifier that reads the intra-sentence blend, no ML dependency),<br>tracks whether you asked for help or wrote the language yourself, and moves N<br>per the ramp policy. The ramp reads the session-cumulative blend and gates on<br>a band: too much target counts as noncompliance, not mastery, so overshoot<br>never ramps N up.
A statusline segment rides along so you always see where the dial is.<br>Reading sv 12%↑ ~11:
sv : target language
12% : current blend target (what the preprompt aims for)
↑ : the gauge just moved up on the last turn (↓ down, nothing = steady)
~11 : the real share of target language measured on the last turn (~ =<br>roughly). No ~N yet means no turn has been measured.
install wires it non-destructively: if you already have a statusline it wraps<br>it and appends the segment, if you don't it adds one. It never edits or replaces<br>your statusline.
The blend only ever grows when the real measured share holds the target and you<br>are not asking for help.
Quick start
./languageme init sv # seed Swedish at 10%<br>./languageme install # wire hooks + statusline (edits ~/.claude/settings.json)<br>./languageme status # target, blend %, recent measurements, ramp state
The preprompt loads at SessionStart, so the drip starts on your next Claude<br>Code session. To activate it in the current one without leaving, run /clear<br>(it re-fires SessionStart). Until the first turn is measured the statusline<br>shows the target with no ~N, and the gauge stays put; the ~N and any ramp<br>appear once a turn has run under the drip.
Put it on your PATH if you like: ln -s "$PWD/languageme" ~/bin/languageme.<br>The hooks call it by absolute path, so a symlink is optional.
Switch target any time: languageme lang sv|es|lv. The gauge and ramp follow<br>the new language.
Ramp policies (languageme ramp )<br>)" href="#ramp-policies-languageme-ramp-mode">
mastery (default). Ramps one step after 3 distinct sessions whose<br>cumulative blend lands in the target band (not too little, not too much) with<br>zero help asked. Each session counts once, however many turns it ran. Writing<br>the language yourself adds a bonus step. Overshoot or asking for help resets<br>the streak.
calendar. One step per monitored session until the goal. Hands-off, blind<br>to whether you're keeping up.
manual. Never auto-moves. You bump it: languageme bump +5.
Natural-language overrides always win, both directions, and they are<br>language-aware. Say "too much swedish" (or the target's own words, "för mycket<br>svenska", "demasiado español", "trop de français") in chat...