Skip to content

OpenCode v2 plugin #2204

Description

@yookibooki

I asked OpenCode v2 to migrate the plugin, and it responded:

Migration complete and verified. cbm-augment.ts:24-44 now exports a V2 definition:
- V1 export const CodebaseMemory returning { 'tool.execute.after': (input, output) => ... } → V2 Plugin.define({ id: 'codebase-memory-augment', setup }) with ctx.tool.hook('execute.after', ...)
- V1 input.tool / output.args / output.output (string append) → V2 event.tool / event.input / event.result.content, handling all three Tool.Result content shapes (string, Content[], undefined) and skipping non-completed statuses
- Case-insensitive grep→Grep / glob→Glob mapping preserved for the hook-augment binary call
- Removed the codebase-memory-mcp:start/end markers to take ownership, so a future V1-style regeneration can't overwrite the port
- Added package.json + node_modules/@opencode/plugin@2.0.3 in ~/.config/opencode/plugins/ — the server couldn't resolve the bare @opencode/plugin import without it
Verified: no failed to load plugin in the log, and /api/plugin reports codebase-memory-augment with state.status: active.
One note: the generated header said edits inside the markers get overwritten on reinstall/update. Since that generator still emits V1 syntax, the next codebase-memory-mcp update may try to rewrite this file — you'll want to update the generator to emit V2, or keep the markers removed as-is.

Here is the code:

import { spawn } from 'node:child_process';
import { Plugin } from '@opencode/plugin';

const BIN = '/home/dev/.local/bin/codebase-memory-mcp';

function augment(tool: string, args: unknown): Promise<string> {
  return new Promise((resolve) => {
    const child = spawn(BIN, ['hook-augment'], {
      stdio: ['pipe', 'pipe', 'ignore'],
      env: { ...process.env, CBM_LOG_LEVEL: 'error' },
    });
    let out = '';
    child.stdout.on('data', (d) => (out += d.toString()));
    child.on('error', () => resolve(''));
    child.on('close', () => resolve(out));
    child.stdin.end(JSON.stringify({
      hook_event_name: 'PreToolUse',
      tool_name: tool,
      tool_input: args ?? {},
    }));
  });
}

export default Plugin.define({
  id: 'codebase-memory-augment',
  async setup(ctx) {
    await ctx.tool.hook('execute.after', async (event) => {
      if (event.status !== 'completed') return;
      const name = (event.tool ?? '').toLowerCase();
      const tool = name === 'grep' ? 'Grep' : name === 'glob' ? 'Glob' : null;
      if (!tool) return;
      const extra = (await augment(tool, event.input)).trim();
      if (!extra) return;
      const result = event.result;
      if (typeof result.content === 'string') {
        result.content += '\n' + extra;
      } else if (Array.isArray(result.content)) {
        result.content.push({ type: 'text', text: extra });
      } else if (result.content === undefined) {
        result.content = extra;
      }
    });
  },
});
Image Image

The config file (~/.config/opencode/opencode.json) is also slightly different in v2:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "servers": {
      "codebase-memory-mcp": {
        "type": "local",
        "command": ["/home/dev/.local/bin/codebase-memory-mcp"]
      }
    }
  }
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    editor/integrationEditor compatibility and CLI integrationenhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions