Skip to content

Updater

OpenCode installs a plugin into a cache directory named after the spec you wrote, and never resolves that spec again. So some-plugin@latest — or no version at all — means the release that was newest the day you first installed it, for ever. Restarting does not move it, and nothing anywhere tells you which release you are really running: the config says latest, and nothing says 0.1.2.

The Updater lists every plugin you have, shows what is running beside what your config says and what is published, and updates the ones you pick.

/plugins-update inside OpenCode.

plugin running config published
▌[✓] opencode-subagent-statusline 1.2.3 latest ! 1.3.0 ↑
[✓] opencode-command-hooks 0.6.1 @0.6.1 0.7.1 ↑
opencode-cockpit 0.4.3 ~/code/cockpit local
12 built into OpenCode
ColumnSays
runningThe version actually loaded, read from the installed package — not from the config
configWhat your config asks for. latest ! is a spec that will not move on its own
publishedThe newest release on your registry. ? when it did not answer — never “current”

Short of room, the list gives up config first and then running; the published version and the state stay at every width, and a long name is cut rather than run into its version.

What needs a decision comes first and is selected for you. Plugins built into OpenCode are one line, and a plugin loaded from a path is listed but never touched: it is updated with git.

Key
j k / ↓ ↑Move
spaceSelect or clear the plugin under the cursor
aSelect every update
enterReview what will change — then enter again to do it
escBack from the review; close the list
rAfter an update: retry what failed
cAfter an update: copy the commands that fix what is still wrong

The review shows every file and every spec that will change, and every cache directory that will be removed, before anything is written. Then, for each plugin:

  1. Pins an exact version — the only kind of spec OpenCode will not freeze — by running OpenCode’s own opencode plugin <name>@<version> --force. OpenCode edits its own config, in its own format, comments kept. The Updater never writes a config file itself.
  2. Removes the stale cache directories, @latest included, once the new version is installed. If the install failed, the old copy is kept: it is the one that still runs.
  3. Reads every file back. opencode plugin prints “Installed” even over an entry it left alone, so the only evidence that counts is disk. The result says what was confirmed — ✓ 2 configs say @1.3.0 · 1 dir removed — or what is still wrong, with the exact command that fixes it.

Restart OpenCode afterwards to load what was updated.

An old copy of a plugin cannot update itself: it predates whatever would fix it. This runs from npm instead of from the copy that is stuck, so it works whatever version you are on:

Terminal window
npx opencode-cockpit@latest update # or: bunx opencode-cockpit@latest update

It prints the same list and the same review, asks before writing anything, and reads the files back the same way. --dry-run shows the plan and writes nothing, --only <name> updates one plugin, and --yes does not ask.

The Updater edits OpenCode 1’s files only. On OpenCode 2, /plugins-update says what to do instead: change the version in your opencode.json plugin entry, run opencode service restart, and restart OpenCode. The restart matters — OpenCode 2’s background service loads plugins once, when it starts, and keeps the old agent side until it restarts. npx opencode-cockpit@latest update says the same when it finishes on a machine with OpenCode 2, and doctor warns when the service still runs an older Cockpit.

  • A project’s root opencode.json. opencode plugin writes a project’s .opencode/ directory and never edits a root-level opencode.json, so those rows say edit by hand — and the result checks them like everything else.
  • npm’s cache owned by someone else. Every install goes through npm; if ~/.npm holds files from an old sudo npm, the install fails with EACCES. The result says so and gives the fix, sudo chown -R "$(whoami)" ~/.npm, before the retry.
  • A private registry is used when npm is configured for it through npm_config_registry.

Once a day the Updater asks the registry about every plugin you have, and if something is behind, says so once: 2 plugin updates available. Run /plugins-update. The same set is not announced again. To turn it off:

~/.config/opencode-cockpit/config.json
{ "updater": { "updateCheck": false } }

Shell’s old ui.updateCheck is no longer read: a file that still has it gets a doctor line naming updater.updateCheck, and /cockpit-setup moves it here.