{"slug": "claudish-to-english", "title": "Claudish to English", "summary": "A working prototype plugin for Claude Code, named Claudish to English, rewrites assistant messages into plain English using a local LLM via ollama, and is display-only, preserving the original text in transcripts. The plugin fails open—if ollama is down or a model is missing, users see Claude's original output unchanged—and requires ollama, a pulled model (default gemma4:26b-mlx, ~17 GB), jq, and curl. It is installable from the gvzdv/claudish-to-english marketplace or the Anthropic community marketplace after review, and all behavior is controlled by CLAUDISH_* environment variables.", "body_md": "A Claude Code plugin that shows a **plain-English rewrite** of each assistant\nmessage, produced by a **local LLM via ollama**. It is **display-only**: Claude's\nown reasoning and the saved transcript keep the original text — only what you\nread on screen changes.\n\nAn optional second hook rewrites **Markdown files** into plain English when they\nare written or edited (opt-in, off by default).\n\nStatus: working prototype. Every hook fails\n\nopen— if anything goes wrong (ollama down, timeout, missing dependency), you simply see Claude's original text. The plugin can never swallow or corrupt an answer.\n\nThis plugin shells out to a **local** model. Nothing works until these are in place:\n\n| Requirement | Why | Install |\n|---|---|---|\nollama, running |\nDoes the rewriting, locally | `brew install ollama` then `ollama serve` |\n| A pulled model | The actual rewriter | `ollama pull gemma4:26b-mlx` (~17 GB; choose the model that fits into your memory) |\n`jq` |\nParses hook JSON | ships with macOS; else `brew install jq` |\n`curl` |\nTalks to ollama | ships with macOS |\n\nWarm the model once after `ollama serve`\n\n(the first call is a slow cold load):\n\n```\nollama run gemma4:26b-mlx \"hi\"\n```\n\n**If the local model isn't ready, the plugin does nothing to your text** —\nClaude's output shows normally, unchanged. That is by design, not a bug. It skips\n(fails open) when ollama is down, the request times out, or the model isn't\npulled. The first time that happens in a session it tells you why: the display\nhook appends a one-line notice on screen, and the Markdown hook shows a\n`systemMessage`\n\n. So a silent skip is never a mystery (once per session; set\n`CLAUDISH_NOTICE=0`\n\nto silence it).\n\n**Pick a model you actually have.** The default is `gemma4:26b-mlx`\n\n. Pull it (as\nabove), or pull a smaller/faster model and point the plugin at it by setting\n`CLAUDISH_MODEL`\n\nto that model's exact ollama tag in your `env`\n\n(see\n[Configuring the plugin](#configuring-the-plugin)). If `CLAUDISH_MODEL`\n\nnames a\nmodel you have not pulled, every rewrite is skipped — with the one-time notice\nabove.\n\nDirectly from this repository (also serves its own marketplace):\n\n```\n/plugin marketplace add gvzdv/claudish-to-english\n/plugin install claudish-to-english@gvzdv-plugins\n```\n\nAfter review by the Anthropic team, the plugin will be available to install from the community marketplace:\n\n```\n/plugin marketplace add anthropics/claude-plugins-community\n/plugin install claudish-to-english@claude-community\n```\n\nIf the install summary says `Run /reload-plugins to activate.`\n\n, run that command.\n\n**Try before installing** (loads it for one session, no install):\n\n```\nclaude --plugin-dir /path/to/claudish-to-english\n```\n\nRun `/reload-plugins`\n\nafter edits; if it doesn't load, check the `/plugin`\n\n**Errors** tab.\n\nAll behavior is controlled by `CLAUDISH_*`\n\nenvironment variables (full list in\n[Configuration](#configuration-env-vars) below). When you install from a\nmarketplace, set them in Claude Code's ** env block in settings.json** — do\n\n**not** edit the plugin's own\n\n`hooks/hooks.json`\n\n, which lives in the read-only\nplugin cache (`~/.claude/plugins/cache/…`\n\n) and is overwritten on every update.For a personal, all-projects setup, use `~/.claude/settings.json`\n\n:\n\n```\n{\n  \"env\": {\n    \"CLAUDISH_MODEL\": \"gemma4:26b-mlx\",\n    \"CLAUDISH_MODE\": \"append\"\n  }\n}\n```\n\nThe hooks are subprocesses Claude Code spawns, so they inherit these. A few things to know:\n\n**Restart Claude Code after editing** The value is captured at launch, so a running session keeps the old one.`env`\n\n.The highest-precedence settings file that defines`env`\n\ndoes not merge across scopes.`env`\n\nsupplies the*entire*block — it isn't combined with lower scopes. Precedence: managed → local → project → user. Keep all your`CLAUDISH_*`\n\nvars in whichever file wins.**Scopes:**`~/.claude/settings.json`\n\n(all your projects) ·`.claude/settings.json`\n\n(shared with a repo, checked in) ·`.claude/settings.local.json`\n\n(just you, just this repo).\n\nQuick one-off without editing a file — hooks inherit the launching shell:\n\n```\nCLAUDISH_MODEL=llama3.2:3b claude\n```\n\nTo confirm the hook is firing, set `CLAUDISH_DEBUG=1`\n\nand watch\n`\"$TMPDIR\"/claudish-to-english/debug.log`\n\n.\n\nClaude Code fires the `MessageDisplay`\n\nevent **once per streamed chunk**, not\nonce per message. Each fire is a separate process carrying `message_id`\n\n,\n`index`\n\n, a `final`\n\nflag, and this chunk's `delta`\n\n(a text fragment, not the\nwhole message). So the hook **buffers every delta** to a temp file (keyed by\n`message_id`\n\n) and only calls the model on the **final** chunk, once the whole\nmessage is known:\n\n```\nchunk 0 (final:false) ─┐\nchunk 1 (final:false) ─┤ append each delta to $TMPDIR/claudish-to-english/<session>/<message>/<index>.part\nchunk 2 (final:false) ─┘  → emit nothing (append) or \"\" (replace)\nchunk 3 (final:true)  ──► reconstruct full message → call ollama once → show the rewrite\n                          → delete the buffer\n```\n\nOn that final chunk it also reads the **original user question** from the\ntranscript and passes it to the model as **context only** — to keep the rewrite\non-topic. The model is told never to answer or repeat the question; it only\nrewrites the assistant's message.\n\n`CLAUDISH_MODE` |\nOn screen | Notes |\n|---|---|---|\n`append` (default) |\nOriginal streams normally, then a `💬 In plain English:` block is appended. |\nSafest. No streaming loss; if the LLM fails you just don't get the extra block. |\n`replace` |\nOnly the simplified version (original chunks suppressed while streaming). | Experimental. Appears all at once after LLM latency; on failure it re-shows the full original. |\n\nA `PostToolUse`\n\nhook (`rewrite-md.sh`\n\n) rewrites Markdown **files** into plain\nEnglish when they are written or edited. Unlike the display hook, this changes\nbytes on disk.\n\n**Opt-in by directory.** It does nothing unless `CLAUDISH_MD_DIR`\n\nis set, and it\nonly touches `*.md`\n\nfiles whose resolved path is inside that directory. Every\nother `README`\n\n, `CLAUDE.md`\n\n, or doc you edit is left alone.\n\n`CLAUDISH_MD_MODE` |\nResult | Notes |\n|---|---|---|\n`sibling` (default) |\nWrites `NAME.plain.md` next to `NAME.md` . |\nNon-destructive; the original is never touched. |\n`overwrite` |\nReplaces `NAME.md` in place. |\nAdds a `<!-- claudish-to-english:rewritten -->` marker so a re-write is skipped (idempotent). A weak model can degrade real docs — use with care. |\n\nIn both modes: YAML frontmatter is split off and re-attached **verbatim**, fenced\ncode is left to the model instruction, short files are skipped, and the write is\natomic. Fail-open here means the file is left **exactly as the agent wrote it**.\n\n**Large files are slow.** `gemma4:26b-mlx`\n\n(the default) rewrites at roughly 60\ntokens/s, so a long plan or spec can take 30–120s. This hook allows up to\n`CLAUDISH_MD_TIMEOUT`\n\n(150s) inside a 180s `PostToolUse`\n\nhook budget; if a rewrite\nstill times out you get the one-time notice above — raise those limits, or set\n`CLAUDISH_MODEL`\n\nto a smaller model.\n\nEnable it for one directory, in sibling mode (the safe default), the same way\nas every other setting — the `env`\n\nblock of your `settings.json`\n\n:\n\n```\n{\n  \"env\": {\n    \"CLAUDISH_MD_DIR\": \"/ABS/PATH/docs/plain\",\n    \"CLAUDISH_MD_MODE\": \"sibling\"\n  }\n}\n```\n\nIn `overwrite`\n\nmode the marker comment is written **after** any YAML\nfrontmatter, so the frontmatter stays on line 1 where parsers expect it.\n\n| Var | Default | Meaning |\n|---|---|---|\n`CLAUDISH_ENABLED` |\n`1` |\nMaster switch. `0` = pass everything through. Read once at session start. |\n`CLAUDISH_OFF_FILE` |\n`~/.claude/claudish-off` |\nRuntime kill switch. While this file exists, rewrites pause — re-checked every message, so unlike env vars it works mid-session. See\n|\n\n`CLAUDISH_MODE`\n\n`append`\n\n`append`\n\nor `replace`\n\n(display hook).`CLAUDISH_MODEL`\n\n`gemma4:26b-mlx`\n\n`CLAUDISH_OLLAMA`\n\n`http://localhost:11434`\n\n`CLAUDISH_MIN_CHARS`\n\n`200`\n\n`CLAUDISH_STUB`\n\n`0`\n\n`1`\n\n= deterministic stub instead of the model (for testing display mechanics).`CLAUDISH_TIMEOUT`\n\n`45`\n\n**display** hook (seconds). Keep it below that hook's`timeout`\n\n(60s).`CLAUDISH_MD_TIMEOUT`\n\n`150`\n\n**Markdown file** hook (seconds). Higher on purpose — a large model rewriting a long doc is slow. Keep it below the`PostToolUse`\n\nhook `timeout`\n\n(180s).`CLAUDISH_DEBUG`\n\n`0`\n\n`1`\n\n= write a debug log to `$TMPDIR/claudish-to-english/`\n\n.`CLAUDISH_NOTICE`\n\n`1`\n\n`1`\n\n= show a one-time, once-per-session notice when a rewrite is skipped because ollama is unreachable, the call timed out, or the model isn't pulled (display hook appends it on screen; Markdown hook uses a `systemMessage`\n\n). `0`\n\n= stay fully silent (pure fail-open).`CLAUDISH_MD_DIR`\n\n*(unset)***Markdown hook opt-in.** Only`*.md`\n\nunder this directory is rewritten. Unset = the Markdown hook does nothing.`CLAUDISH_MD_MODE`\n\n`sibling`\n\n`sibling`\n\n(`NAME.plain.md`\n\n) or `overwrite`\n\n(in place).`CLAUDISH_MD_SUFFIX`\n\n`plain`\n\n`NAME.<suffix>.md`\n\n.In `hooks/hooks.json`\n\nthe display hook (`MessageDisplay`\n\n) has a 60s `timeout`\n\nand\nthe Markdown hook (`PostToolUse`\n\n) has a 180s `timeout`\n\n— the file hook is higher\nbecause a large model rewriting a long document can take a couple of minutes.\n`CLAUDISH_TIMEOUT`\n\nand `CLAUDISH_MD_TIMEOUT`\n\nkeep the LLM call itself bounded\nbelow those ceilings, so it fails open cleanly instead of being killed mid-write.\n\n**Quick kill switch:** set `CLAUDISH_ENABLED=0`\n\nor disable the plugin (both apply\nonly from the next session start), or `touch ~/.claude/claudish-off`\n\nto pause a\nsession that's already running — see [Toggling mid-session](#toggling-mid-session)\nbelow.\n\n`CLAUDISH_ENABLED`\n\nand the other env vars are read once, when a session launches,\nso they can't pause rewrites in a session that's already running. For that, both\nhooks also check a **flag file** on every invocation — each fire is a fresh\nprocess, so the check is always live:\n\n```\ntouch ~/.claude/claudish-off   # pause rewrites, effective on the next message\nrm    ~/.claude/claudish-off   # resume\n```\n\nYou create and remove this file yourself; nothing creates it on install, and its\nabsence is the normal \"on\" state. While it exists, `ENABLED`\n\nis forced to `0`\n\nand\nthe fail-open path leaves Claude's original text untouched. Point a hotkey at a\ntwo-line toggle script to flip rewrites from the keyboard across all running\nsessions at once. Override the path with `CLAUDISH_OFF_FILE`\n\n.\n\nThe request sends `\"think\": false`\n\n. Models with a hidden reasoning phase\notherwise spend most of their time generating reasoning tokens you never see —\nmuch slower for identical output quality on this simple task. Keep it off.\n\nThe rewriter runs **entirely locally** against ollama, so **no conversation\ncontent leaves your machine**. If you ever point `CLAUDISH_OLLAMA`\n\nat a\nremote/hosted endpoint, that context (which can include file contents from tool\nresults) would be sent off-box — don't do that unless you understand and accept\nit.\n\n```\nclaudish-to-english/\n├── .claude-plugin/\n│   ├── plugin.json         # plugin manifest\n│   └── marketplace.json    # so the repo can be added as a marketplace directly\n├── hooks/\n│   └── hooks.json          # MessageDisplay -> rewrite.sh ; PostToolUse -> rewrite-md.sh\n├── rewrite.sh              # display-rewrite hook\n├── rewrite-md.sh           # markdown-file rewrite hook (opt-in)\n├── LICENSE\n└── README.md\n```\n\nMIT — see [LICENSE](/gvzdv/claudish-to-english/blob/main/LICENSE).", "url": "https://wpnews.pro/news/claudish-to-english", "canonical_source": "https://github.com/gvzdv/claudish-to-english", "published_at": "2026-08-11 22:23:30+00:00", "updated_at": "2026-08-11 22:41:24.786830+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "large-language-models"], "entities": ["Claude Code", "Claudish to English", "ollama", "gemma4:26b-mlx", "Anthropic", "gvzdv/claudish-to-english", "anthropics/claude-plugins-community"], "alternates": {"html": "https://wpnews.pro/news/claudish-to-english", "markdown": "https://wpnews.pro/news/claudish-to-english.md", "text": "https://wpnews.pro/news/claudish-to-english.txt", "jsonld": "https://wpnews.pro/news/claudish-to-english.jsonld"}}