OpenCode version affected: 1.17.9
SDK contract
From @opencode-ai/plugin/dist/index.d.ts (SDK 1.17.11, used by OpenCode CLI 1.17.9):
export type Plugin = (input: PluginInput, options?: PluginOptions) => Promise<Hooks>;
export type PluginModule = {
id?: string;
server: Plugin;
tui?: never;
};
OpenCode's plugin loader expects the V1 default export to satisfy PluginModule, i.e. it must expose a .server property that is the actual plugin function.
Actual oc-sync export shape
oc-sync/dist/index.js ships:
import { OpencodeSyncPlugin } from './plugin/index.js';
// Only export the plugin as default - OpenCode expects a single default export
export default OpencodeSyncPlugin;
The default export is a bare async function (Plugin), not a { server: Plugin } object. Runtime checks confirm this:
const m = await import('file:///.../node_modules/oc-sync/dist/index.js');
typeof m.default; // 'function'
m.default?.server; // undefined
Object.keys(m); // ['default']
The function itself works perfectly when called directly — the failure is purely a contract mismatch with the OpenCode loader.
Working example
@slkiser/opencode-quota loads correctly because its default export matches the contract:
{ id: '@slkiser/opencode-quota', server: QuotaToastPlugin }
Suggested fix
Change the default export in src/index.ts from:
export default OpencodeSyncPlugin;
to:
import { OpencodeSyncPlugin } from './plugin/index.js';
const plugin: PluginModule = {
id: 'oc-sync',
server: OpencodeSyncPlugin,
};
export default plugin;
(or equivalent for the current SDK contract).
Local shim workaround
Until this is fixed upstream, users can wrap oc-sync in a local V1 shim and reference that path in opencode.json:
// oc-sync-v1-shim.ts
import oc from 'oc-sync';
const plugin = { id: 'oc-sync', server: oc as any };
export default plugin;
Then register the absolute path to that file in the plugin array instead of the oc-sync package name.
Thanks for the useful plugin — happy to help test a fixed release.
OpenCode version affected: 1.17.9
SDK contract
From
@opencode-ai/plugin/dist/index.d.ts(SDK 1.17.11, used by OpenCode CLI 1.17.9):OpenCode's plugin loader expects the V1
defaultexport to satisfyPluginModule, i.e. it must expose a.serverproperty that is the actual plugin function.Actual
oc-syncexport shapeoc-sync/dist/index.jsships:The default export is a bare async function (
Plugin), not a{ server: Plugin }object. Runtime checks confirm this:The function itself works perfectly when called directly — the failure is purely a contract mismatch with the OpenCode loader.
Working example
@slkiser/opencode-quotaloads correctly because its default export matches the contract:Suggested fix
Change the default export in
src/index.tsfrom:to:
(or equivalent for the current SDK contract).
Local shim workaround
Until this is fixed upstream, users can wrap
oc-syncin a local V1 shim and reference that path inopencode.json:Then register the absolute path to that file in the
pluginarray instead of theoc-syncpackage name.Thanks for the useful plugin — happy to help test a fixed release.