An OpenCode plugin that translates user prompts to English before they reach the main model, then translates assistant text back to the configured language.
- Translate user prompts to English before the main model request.
- Translate completed assistant prose to the configured language.
- Preserve tool calls, tool arguments, tool output, reasoning, code, paths, URLs, commands, diffs, and errors.
- Toggle translation with
/translateorCtrl+Shift+T. - Show the current state and language in the TUI prompt badge.
- Use an explicit translation model or OpenCode's global
small_model. - Share one global
translate.jsonconfiguration between the server and TUI plugins. - Persist the toggle state through OpenCode KV.
- Fail open: translation failures never replace the original content with an error.
- OpenCode
>=1.18.5 - Bun
- Node-style npm plugin loading
Install the package through OpenCode:
opencode plugin opencode-auto-translate@latestThe package exposes separate server and TUI entrypoints. OpenCode can therefore load it from both configuration files:
// ~/.config/opencode/tui.json
{
"$schema": "https://opencode.ai/tui.json",
"plugin": ["opencode-auto-translate@latest"],
}OpenCode caches npm plugins. To force a newly published @latest version to be downloaded, close OpenCode and remove its cache entry:
rm -rf ~/.cache/opencode/packages/opencode-auto-translate@latestUse opencode debug paths to find the cache root when it differs from ~/.cache/opencode.
For headless use, configure only the server plugin:
// ~/.config/opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-auto-translate@latest"],
}Server-only mode translates prompts and assistant text but does not provide the TUI toggle, keybind, badge, toast notifications, or KV persistence. A TUI-only installation cannot translate server messages.
The recommended setup is one global translate.json file. The plugin checks these locations in order:
$OPENCODE_CONFIG_DIR/translate.json$XDG_CONFIG_HOME/opencode/translate.json~/.config/opencode/translate.json
Only the global file is read. Project-level translate.json files are ignored.
{
"$schema": "https://unpkg.com/opencode-auto-translate@latest/dist/translate.schema.json",
"enabled": true,
"model": "openai/gpt-5.6-luna",
"variant": "minimal",
"lang": "Spanish",
"input": "show original",
"output": "show translation"
}The published schema is generated from the same Zod schema used by both runtimes. It provides editor autocomplete, descriptions, defaults, enum suggestions, and validation. Unknown properties are rejected by the schema so misspelled options are visible in the editor.
| Option | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | unset | Initial translation state used when no persisted TUI state exists. |
model |
string | unset | Translation model in provider/model format. Overrides OpenCode's small_model. |
variant |
string | unset | Optional provider-specific model variant. |
lang |
string | English |
Target language for assistant translations and the TUI badge. |
input |
enum | show original |
User-prompt display mode. Currently only show original is supported by OpenCode's transform API. |
output |
enum | show original |
Assistant display mode. |
Valid output values are:
show original: display only the English assistant text.show translation: display the English text, separator, and localized translation.show original + translation: display the same English text plus the[Translation]label and localized translation.
The translation-inclusive format is:
English original
----------------------------------------
[Translation]
Localized translation
The English original is retained because hiding it can break future model context with the current OpenCode API.
Missing, unreadable, malformed, or invalid configuration files fail open. The plugin logs the problem and falls back to inline options and defaults. Options are resolved in this order:
- Built-in defaults.
- Global
translate.json. - Inline plugin options.
- Persisted TUI enabled state from OpenCode KV.
Inline options remain supported, but using the shared file avoids server and TUI configuration drift:
{
"plugin": [
[
"opencode-auto-translate@latest",
{
"model": "openai/gpt-5.4-mini",
"variant": "minimal",
"lang": "Spanish",
"enabled": true,
"input": "show original",
"output": "show original + translation",
},
],
],
}The translation model is selected in this order:
modelfrom inline options ortranslate.json.- OpenCode's global
small_model.
Both model values must use the provider/model format. Configure small_model in opencode.json when an explicit plugin model is not needed.
- The user writes a prompt in the configured language.
- The plugin translates the model-facing user text to English.
- The main model receives English and responds in English.
- Completed assistant
TextPartcontent is translated tolangfor display.
Input translation changes only the model-facing message, so visible user history keeps the original text. Tool calls, tool arguments, tool output, reasoning, code, paths, URLs, commands, diffs, and errors are not translated. Native question and permission prompts remain English because the current plugin API does not expose a safe mutable display hook for them.
Each translation uses a temporary internal session with the selected model. Sessions are deleted after use, and repeated text is cached for the current plugin instance. Translation sessions are excluded from the main session token count but still incur provider cost.
If configuration lookup, session creation, translation, response parsing, or cleanup fails, the original content remains unchanged and the failure is logged without breaking the main request.
Use /translate from the command palette or press Ctrl+Shift+T. The prompt badge shows the current state, for example:
[translate: on -> Spanish]
The TUI reads persisted KV state first. Without a stored value, it uses enabled from translate.json. Startup publishes the initial state to the server without showing a toast. User-triggered toggles update KV, update the badge, show a toast, and publish the state. If publishing fails, the local state is rolled back.
Install dependencies and run the complete verification gate:
bun install
bun run check:allThe build performs two tasks:
- Generates
dist/translate.schema.jsonfrompluginOptionsSchema. - Builds
dist/server.jsanddist/tui.js.
To load a local build directly:
bun run build// ~/.config/opencode/opencode.json
{
"plugin": ["/absolute/path/to/opencode-auto-translate/dist/server.js"],
}// ~/.config/opencode/tui.json
{
"plugin": ["/absolute/path/to/opencode-auto-translate/dist/tui.js"],
}The local build uses the same shared translate.json. Restart OpenCode after changing plugin files or OpenCode configuration because plugins and configuration are loaded at startup.
check:all runs TypeScript typechecking, Bun tests, Oxlint, duplicate detection, Knip, Fallow analysis, and the production build. Git hooks lint staged TypeScript files before commits and run check:all before pushes.
GitHub Actions publishes releases to npm when a GitHub Release is published. The release tag must match the package version, such as v0.1.0 for version 0.1.0.
The first npm publication must be performed manually. After the package exists, configure npm Trusted Publishing for dogalyir/opencode-auto-translate with workflow publish.yml and the GitHub npm environment. Later releases require updating version, merging to main, and publishing the matching GitHub Release.
MIT