Contributing a mod
1. Make the change in the harness
git clone https://github.com/anomalyco/opencode && cd opencode
git checkout v1.18.31
Pick the latest release tag, not the default branch. Mods are pinned to releases because that is what users have installed and what CI can reproduce.
Use the Bun version the release pins in its package.json packageManager field; open-mods does this for you when it builds, but for your own dev runs install it with curl -fsSL https://bun.sh/install | bash -s bun-v1.3.14. Change whatever you want. Commit as you go; each commit becomes one patch, so keep them meaningful (feat(tui): add vim keys to the session list). Keep the harness's own tests and typecheck passing:
cd packages/tui && bun run typecheck
2. Pack it
From your checkout of this registry:
open-mods pack ../opencode --name my-mod --local # try it: open-mods install opencode/my-mod
open-mods pack ../opencode --name my-mod # ready to publish
--local writes the mod under ~/.open-mods/local, where it is installable but not part of the registry. Without it, pack finds the release tag below your commits, runs git format-patch, and writes mods/opencode/my-mod/ with a mod.json and a README stub. Fill in the description, tags, and license. Describe what the mod changes and why in the README; that page is what people read before they build it.
mod.json fields:
| field | meaning |
|---|---|
name |
lowercase, digits, hyphens; unique within the harness |
harness |
id of a file in harnesses/ |
upstream.ref / upstream.commit |
the harness release the mod supports and its exact commit. This is the mod's version. CI moves it forward automatically when the patches still apply and build on a newer release. |
patches |
ordered list under patches/, generated by pack |
conflicts |
optional; other mods this one is known not to stack with |
maintainers |
optional; GitHub handles the bot mentions when a new release breaks the mod. Defaults to author.github. |
status.json next to mod.json is written by CI only. It records the last release the mod was tested against and whether it passed.
3. Check it
open-mods check mods/opencode/my-mod --build
This clones the harness into a temp directory, applies your patches at the pinned commit, and builds. CI runs the same command on every pull request. --typecheck instead of --build is the quick version, and what the release watch runs against each new release.
4. Open a pull request
One mod per PR. The PR description should say what the mod does and include a screenshot or recording if it changes the UI.
A mod changes the harness itself. That is the whole point: it reaches what plugins, skills and MCP servers cannot. A submission that only adds a skill, a plugin or an MCP server belongs in that system's own channel, such as npm, skills.sh or the harness's config, and will be pointed there. If your mod adds a new tool or behavior the agent needs to know about, describe it in the harness's own source, where its built-in tools are described, rather than shipping a skill beside it.
Reviewers look for:
- Patches that apply at the pinned commit and build.
- A clear description of every file touched.
open-mods infoprints the list. - No network calls, telemetry, or credential access that the README does not mention.
- A license compatible with the harness.
Updating a mod for a new release
cd ../opencode
git fetch --tags && git checkout v1.19.0
git am -3 ../open-mods/mods/opencode/my-mod/patches/*.patch # fix conflicts if any
open-mods pack . --name my-mod --force
Open a PR. Mods have no version number of their own: a mod is "for OpenCode 1.19.0", and that moves forward automatically when CI finds the patches still apply and build on a new release. You only need to do this by hand when CI opens an issue saying the mod no longer supports a release.
Adding a harness
Add harnesses/<id>.json following schema/harness.schema.json. It needs the git URL, the install, typecheck and build commands, and the path of the built executable. Open a PR with one example mod so the pipeline is exercised end to end.