Keep OpenCode session titles meaningful. opencode-retitle regenerates a
session title at three moments:
- After every N user turns (default 5).
- After a compaction finishes.
- After the first assistant response in a forked session.
It also protects titles you set by hand: once a title it did not write appears, retitling pauses for that session until you re-enable it.
Add it to opencode.json(c) and pass settings under options:
Every setting lives in opencode.json(c), under the plugin's options object;
there is no separate config file. Settings you leave out fall back to the
built-in defaults. OpenCode merges the global
(~/.config/opencode/opencode.json(c)) and project opencode.json(c) files
before the plugin runs, with the project overriding the global.
/retitle-status— report whether this session's title was set manually or by opencode-retitle, how far the turn counter is, and which settings differ from the defaults. Makes no model call./retitle-enable— clear the manual-rename pause for this session and retitle now. Use this when you renamed a session by hand and want automatic retitling back.
Both are TUI slash commands that show their result as a toast.
We cannot tell a manual rename apart from another plugin, or from you asking the agent to rename the session. All three mean "a meaningful title is now in place", which is exactly when retitling should stop. So the plugin attributes every rename by elimination, using title shapes that OpenCode itself produces:
| New title | Attributed to | Effect |
|---|---|---|
| equals the last title we wrote | opencode-retitle | keep going |
New session - <ISO> / Child session - <ISO> |
OpenCode default | record baseline |
<base> (fork #N) |
OpenCode fork | record baseline |
| arrives while the built-in generator is running | OpenCode auto-title | record baseline |
| anything else | manual / external | pause (when respectManualRename) |
Sessions the plugin meets mid-flight. The first time the plugin sees a session it inspects the current title. A title that is not a default, a fork title, or one we wrote is treated as manually chosen, so the session starts paused. This only affects a session the plugin has never recorded; state is persisted, so a restart does not re-trigger it.
This is the one case where an auto-generated title can be mistaken for a manual
one: if OpenCode generated the title before the plugin loaded, there is no way to
attribute it. Set lockExistingTitles to false to retitle such sessions
instead of pausing them.
Timing. The marker that OpenCode is generating a title is shared across
plugin instances and expires after builtinGraceMs (45 seconds by default). A
rename you make in that window, right after an auto-generated title, is
attributed to OpenCode and does not pause retitling.
- The turn counter means prompts since the last rename. Only real user
prompts count, and it resets after every retitle — turn, compaction, fork, or
/retitle-enable— so two renames never bunch up and each interval is a full N prompts. - Fork retitling is armed when a session is forked and fires on the first response in the new session.
- Titles are generated by the session's own model unless
modelis set, from a recent transcript with code blocks stripped. The prompt is capped at 1000 characters per message line and 3100 characters overall, so a single large paste cannot inflate it.
{ "$schema": "https://opencode.ai/config.json", "plugins": [ { "package": "opencode-retitle", "options": { "turns": 5, // retitle every N user prompts; 0 disables "onCompaction": true, // retitle after a compaction "onFork": true, // retitle after the first response in a fork "respectManualRename": true, // pause retitling once a foreign title appears "lockExistingTitles": true, // pause a session that already had a title when first seen "builtinGraceMs": 45000, // ms a built-in title stays attributable to OpenCode "model": null, // "providerID/modelID"; null = the session's model "titleMaxLength": 60, "minPromptLength": 10, // skip when there is too little user text "debug": false // log decisions to the OpenCode log } } ] }