Skip to content
38 changes: 27 additions & 11 deletions UPDATES.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,35 @@
# How OMMS updates

OMMS is one npm package, `om-memory-system`. Each host keeps its own copy of it. Pi and OpenCode never install an update by themselves. Claude Code does only when you turn on auto-update for the `omms` marketplace. Otherwise you choose when to update, then restart the host. You update one host. Every other part of OMMS on the machine then runs that copy. See [One update updates every host](#one-update-updates-every-host).
OMMS is one npm package, `om-memory-system`. Each host keeps its own copy of it. Pi and OpenCode install each new release by themselves, then ask you to restart. Claude Code does the same through its session-start hook. Claude Code's marketplace auto-update is a separate setting that you can turn on. You update one host. Every other part of OMMS on the machine runs that copy. See [One update updates every host](#one-update-updates-every-host).

| Host | How you hear about a new release | Update with | Then |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
| Pi | Pi shows an update notice when it starts | `pi update npm:om-memory-system` | Restart Pi |
| OpenCode v2 | The footer shows `omms:connected · 4.3.0 available`, and a toast tells you the command. `opencode plugin check` also lists it | `opencode plugin update om-memory-system` | Restart OpenCode, including its background server |
| Claude Code | The status line shows `omms: connected · 4.4.0 available`, and a toast tells you the command. `claude plugin list` shows the installed version. Auto-update is off until you turn it on for the `omms` marketplace | `claude plugin update omms@omms` | Run `/reload-plugins` or start a new session |
| Web app and terminal command | The sidebar shows the running version. An **Update** button appears in the sidebar footer when npm has a newer release. The Settings page **Web app** card shows the global version | Nothing. They run the newest copy. Or select **Update**, then **Update web app**: it installs the release globally with npm and restarts the web app on it. A global install from 4.3 or earlier needs one `npm i -g om-memory-system@latest` | The next host start replaces an older web app |
| Host | How you hear about a new release | Update with | Then |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| Pi | OMMS installs it in the background. The footer shows `omms: ✔ · 4.3.0 installed, restart`, and one message tells you to restart Pi | `pi update npm:om-memory-system` (OMMS runs it for you) | Restart Pi |
| OpenCode v2 | OMMS installs it in the background. The footer shows `omms: ✔ · 4.3.0 installed, restart`, and one message tells you to restart OpenCode and run `opencode service restart`. `opencode plugin check` also lists new releases | `opencode plugin update om-memory-system` (OMMS runs it for you) | Restart OpenCode, then run `opencode service restart` |
| Claude Code | The status line shows `omms: connected · 4.4.0 available`, and a toast tells you the command. `claude plugin list` shows the installed version. Auto-update is off until you turn it on for the `omms` marketplace | `claude plugin update omms@omms` | Run `/reload-plugins` or start a new session |
| Web app and terminal command | The sidebar shows the running version. An **Update** button appears in the sidebar footer when npm has a newer release. The Settings page **Web app** card shows the global version | Nothing. They run the newest copy. Or select **Update**, then **Update web app**: it installs the release globally with npm and restarts the web app on it. A global install from 4.3 or earlier needs one `npm i -g om-memory-system@latest` | The next host start replaces an older web app |

## Why OpenCode needs a manual update
## How Pi and OpenCode update

Your OpenCode config names the plugin without a version: `"om-memory-system"`. That means "latest". OpenCode resolves "latest" once, saves that version in `~/.cache/opencode/npm/`, and keeps using the saved copy. It does not ask npm again at the next start. Run `opencode plugin update om-memory-system` to fetch the new release. That command reads `~/.config/opencode/cli.json`, so add `"plugins": ["om-memory-system"]` there too. See [OpenCode setup](docs/opencode-adapter.md).
When a Pi or OpenCode V2 session starts, OMMS compares its version with npm `latest`. OpenCode checks again every 6 hours. When npm has a newer release that is not a prerelease, OMMS runs the host update command in the background. A second session does not start another update for the same release within 30 minutes.

OMMS 4.3.0 and later check npm when OpenCode starts and then every 6 hours. When a newer release exists, the footer and a toast say so. Set `OMMS_DISABLE_UPDATE_CHECK=1` to turn the check off.
While the update installs, OMMS shows `om-memory-system <version> is installing in the background.` When it ends:

- Success: OMMS checks that the new version is on disk. The footer then shows `omms: ✔ · <version> installed, restart`, and one message tells you to restart the host.
- Failure: the footer shows `· <version> available`, and one message names the update command. Run it yourself. OMMS also shows this when the update command ends with success but the new version is not on disk.

You must restart Pi or OpenCode to load the new copy. OMMS never restarts the host. OpenCode's background server keeps the old copy in memory. For OpenCode, also run `opencode service restart`.

OMMS does not run the update in two cases. The notice then shows `<version> available` and the command to run.

- A local checkout. OMMS does not load from a `node_modules/om-memory-system/` folder.
- A pinned version. For Pi, that is a `packages` entry `npm:om-memory-system@<version>` or a settings file that OMMS cannot read. See [Stay on one version](#stay-on-one-version).

Your OpenCode config names the plugin without a version: `"om-memory-system"`. That means "latest". OpenCode resolves "latest" once and saves that version in `~/.cache/opencode/npm/`. The OMMS update refreshes that copy. The `opencode plugin update` command reads `~/.config/opencode/cli.json`, so add `"plugins": ["om-memory-system"]` there too. See [OpenCode setup](docs/opencode-adapter.md).

Set `OMMS_DISABLE_UPDATE_CHECK=1` to turn off the npm check and the update. The check sends no session content.

OpenCode keeps each update in a new folder under `~/.cache/opencode/npm/om-memory-system@latest/`, about 900 MB each, and never removes the old ones. When the OpenCode background service starts, OMMS removes the older OMMS folders. It keeps the running folder, newer folders, the folder in `~/.omms/runtime.json`, and folders without a readable version. It removes nothing while the running folder is less than 24 hours old. See [Updating and upgrading](docs/upgrading.md#updating-omms).

## Claude Code updates

Expand Down Expand Up @@ -41,6 +57,6 @@ The login web app runs one copy of OMMS for every host. The login item runs the

## Stay on one version

Install with a version number, for example `pi install npm:om-memory-system@4.2.0` or `opencode plugin add om-memory-system@4.2.0`. OpenCode skips exact versions during `plugin check` and `plugin update`. OMMS can still show its own newer-release notice for a pinned OpenCode install. Set `OMMS_DISABLE_UPDATE_CHECK=1` to turn that notice off.
Install with a version number, for example `pi install npm:om-memory-system@4.2.0` or `opencode plugin add om-memory-system@4.2.0`. OpenCode skips exact versions during `plugin check` and `plugin update`. OMMS does not update a pinned install in the background. It can still show its own newer-release notice. Set `OMMS_DISABLE_UPDATE_CHECK=1` to turn that notice off.

More detail: [Updating and upgrading](docs/upgrading.md).
57 changes: 57 additions & 0 deletions docs/adr/045-hosts-update-omms-with-their-own-command.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# ADR-045: Pi and OpenCode update OMMS by running the host's own update command

- **Date:** 2026-11-07
- **Status:** Accepted
- **Deciders:** Aizat Hawari
- **Change:** [`pi-opencode-auto-update`](../../openspec/changes/archive/2026-11-07-pi-opencode-auto-update/proposal.md), [`host-update-verify-and-prune`](../../openspec/changes/archive/2026-11-08-host-update-verify-and-prune/proposal.md)

## Context

Claude Code installed new OMMS releases without a typed command. Pi and OpenCode only told the user that a release existed. The user had to run `pi update npm:om-memory-system` or `opencode plugin update om-memory-system` and restart the host.

Neither host has a setting for plugin auto-update. Both hosts install OMMS from npm `latest` into their own folders. A running host keeps the loaded copy in memory, so a restart is always needed.

## Decision

1. **OMMS runs the host's own update command.** At session start, Pi and OpenCode V2 compare the OMMS version with npm `latest`. When npm has a newer release that is not a prerelease, OMMS runs `pi update npm:om-memory-system` or `opencode plugin update om-memory-system` in a detached process. OpenCode checks again every 6 hours.
2. **A marker file per host prevents repeat updates and records the result.** The files are `~/.omms/pi-plugin-update.json` and `~/.omms/opencode-plugin-update.json`. A second session does not start another update for the same release within 30 minutes. The detached script writes `outcome` to the marker. The plugin reads the marker every 60 seconds for up to 10 minutes.
3. **OMMS skips pinned and local installs.** The notice then shows `· <version> available` and the command. `OMMS_DISABLE_UPDATE_CHECK=1` turns the check and the update off.
4. **OMMS never restarts the host.** A restart would end open sessions. The footer shows `· <version> installed, restart`. For OpenCode, the message also names `opencode service restart`, because the background service keeps the old copy loaded.
5. **OMMS shows `installed, restart` only after the new version is on disk.** An exit code of 0 is not enough. When no installed copy holds the new version, OMMS shows `· <version> available` and the command.
6. **OMMS removes old OpenCode copies that it owns.** OpenCode 2.2 stores each update in a new `om-memory-system@latest/<timestamp>/` folder, about 900 MB each, and never removes old folders. When the OpenCode background service starts, OMMS removes older OMMS folders in that cache. It keeps the running folder, newer folders, the folder in `~/.omms/runtime.json`, and folders without a readable version. It removes nothing while the running folder is less than 24 hours old.
7. **Shared code lives in `src/services/host-self-update.ts`.** Claude Code keeps its own module, `src/adapters/claude-code/plugin-self-update.ts`.

## Alternatives Considered

| Option | Rejected Because |
| --------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| A launchd job that runs both update commands hourly | Works on macOS only, sits outside OMMS, and each user must set it up |
| Notice only (the earlier behaviour) | The user must remember to run the command |
| OMMS restarts the host after the update | A restart ends open sessions and can lose work in progress |
| Move Claude Code onto the shared module now | Claude Code works today. The move is a refactor with no new behaviour. It stays a later change. |

## Consequences

Positive:

- Pi and OpenCode users get a new release without a typed command.
- The footer tells the user when a restart is the only step left.
- The disk does not fill with old OpenCode copies.

Negative:

- The user must still restart the host. OpenCode also needs `opencode service restart`.
- OMMS writes two marker files under `~/.omms/`.
- OMMS deletes folders in the OpenCode cache. A TUI or web app that has run an old copy for more than 24 hours can fail to load a module until it restarts.
- Two update modules exist until Claude Code moves onto the shared one.

Neutral:

- Pinned installs and local checkouts keep the notice-only behaviour.
- Pi updates in place and needs no clean-up.

## References

- [Updating and upgrading](../upgrading.md#updating-omms)
- [TDR-071](../tdr/071-opencode-update-live-check-findings.md)
- `src/services/host-self-update.ts`
1 change: 1 addition & 0 deletions docs/adr/ADR_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ Local decision records for OMMS maintainers.
| [042](./042-a-space-bound-store-and-linked-read-only-spaces.md) | A space-bound store and linked read-only spaces | 2026-11-06 | Proposed |
| [043](./043-the-default-space-name-lives-in-the-registry.md) | The Default space name lives in the registry | 2026-11-07 | Proposed |
| [044](./044-new-memory-spaces-get-random-folder-ids.md) | New memory spaces get random folder ids | 2026-11-07 | Proposed |
| [045](./045-hosts-update-omms-with-their-own-command.md) | Pi and OpenCode update OMMS by running the host's own update command | 2026-11-07 | Accepted |
5 changes: 3 additions & 2 deletions docs/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,9 @@ Versions come from commit messages. Use `feat:` (minor), `fix:` (patch),
registry. It reads the stage ID from the newest GitHub Release note. If npm
does not show the version within 150 seconds, the script stops. Wait a few
minutes and run it again. It does not approve a second time.
7. Users with marketplace auto-update get the plugin at their next check. Users
on an unpinned npm install get an update notice.
7. Users with marketplace auto-update get the plugin at their next check. Pi and
OpenCode users on an unpinned npm install get the release installed in the
background and a restart notice.

If you approve another way, run `bun run release:approve` again. It sees the
version on npm, skips the approval, and moves `stable`. Do not wait for the
Expand Down
7 changes: 6 additions & 1 deletion docs/opencode-adapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,12 @@ OpenCode 2.0.22 and later load the plugin's `./tui` entry. It shows OMMS's state
- `omms: ⧖` at start, then `omms: ✔` when the web app answers on `webServerPort`.
- `omms: ✘ web app off` when the web app does not answer. Capture and retrieval keep working.
- `omms: ✘` when the footer cannot start its status check.
- `· <version> available` when npm has a newer release. A toast also names the update command once per start. The plugin checks npm at start and every 6 hours. Set `OMMS_DISABLE_UPDATE_CHECK=1` to turn the check off.
- `· <version> available` when npm has a newer release and OMMS does not install it (local checkout, pinned version, or a failed update). A toast also names the update command once per start.
- `· <version> installed, restart` after OMMS installs the newer release in the background and finds the new version on disk. A toast tells you to restart OpenCode and run `opencode service restart`, because the background service keeps the old copy loaded. While the update installs, a toast says so. The background service also runs the update check, so OpenCode without the TUI (for example OpenChamber or `opencode serve`) updates too. It shows no notice. When the update command ends with success but the new version is not on disk, the footer keeps `· <version> available` and a toast names the update command.

The plugin checks npm at start and every 6 hours. When npm has a newer release, it runs `opencode plugin update om-memory-system` in the background. Set `OMMS_DISABLE_UPDATE_CHECK=1` to turn the check and the update off. See [Updating and upgrading](upgrading.md#updating-omms).

OpenCode 2.2 and later store each update in a new folder, `~/.cache/opencode/npm/om-memory-system@latest/<timestamp>/`, about 900 MB each. When the OpenCode background service starts, OMMS removes the older OMMS folders in the background. It keeps the running folder, every newer folder, the folder in `~/.omms/runtime.json`, and any folder without a readable version. It removes nothing while the running folder is less than 24 hours old. A folder that OMMS cannot remove stays. Each pass writes one `OpenCode cache clean-up` log record with counts only.

The footer reads only the health route and the npm registry's `latest` version. It sends nothing about your sessions.

Expand Down
Loading
Loading