Return TypeScript source for the OpenCode user-level plugin. The plugin hooks into three OpenCode events to mirror the Claude Code hook behaviors: 1. ``file.edited`` — runs ``code-review-graph update --skip-flows`` 2. ``session.created`` — runs ``code-review-graph status`` 3. `
()
| 1380 | |
| 1381 | |
| 1382 | def _opencode_plugin_content() -> str: |
| 1383 | """Return TypeScript source for the OpenCode user-level plugin. |
| 1384 | |
| 1385 | The plugin hooks into three OpenCode events to mirror the Claude Code |
| 1386 | hook behaviors: |
| 1387 | |
| 1388 | 1. ``file.edited`` — runs ``code-review-graph update --skip-flows`` |
| 1389 | 2. ``session.created`` — runs ``code-review-graph status`` |
| 1390 | 3. ``tool.execute.before`` — when the tool is a shell command starting |
| 1391 | with ``git commit``, runs ``code-review-graph detect-changes --brief`` |
| 1392 | |
| 1393 | All handlers use try/catch so errors never break the editor session. |
| 1394 | The plugin uses Bun's ``$`` shell API (provided by OpenCode's plugin |
| 1395 | context) for subprocess execution. |
| 1396 | """ |
| 1397 | return """\ |
| 1398 | import type { Plugin } from "@opencode-ai/plugin" |
| 1399 | |
| 1400 | /** |
| 1401 | * code-review-graph plugin for OpenCode. |
| 1402 | * |
| 1403 | * Keeps the knowledge graph up-to-date and surfaces status |
| 1404 | * information automatically during coding sessions. |
| 1405 | * |
| 1406 | * Installed by: code-review-graph install --platform opencode |
| 1407 | */ |
| 1408 | |
| 1409 | // Helper: run a shell command quietly, swallowing errors. |
| 1410 | async function run($: any, cmd: string): Promise<string> { |
| 1411 | try { |
| 1412 | const result = await $`${cmd}`.quiet() |
| 1413 | return result.stdout?.toString().trim() ?? "" |
| 1414 | } catch { |
| 1415 | return "" |
| 1416 | } |
| 1417 | } |
| 1418 | |
| 1419 | export default (app: any) => { |
| 1420 | // 1. Auto-update graph after file edits |
| 1421 | app.on("file.edited", async ({ $ }: { $: any }) => { |
| 1422 | try { |
| 1423 | await $`code-review-graph update --skip-flows`.quiet() |
| 1424 | } catch { |
| 1425 | // Swallow — graph may not be built yet for this project. |
| 1426 | } |
| 1427 | }) |
| 1428 | |
| 1429 | // 2. Show graph status when a new session starts |
| 1430 | app.on("session.created", async ({ $ }: { $: any }) => { |
| 1431 | try { |
| 1432 | const result = await $`code-review-graph status`.quiet() |
| 1433 | const output = result.stdout?.toString().trim() |
| 1434 | if (output) { |
| 1435 | console.log("[code-review-graph]", output) |
| 1436 | } |
| 1437 | } catch { |
| 1438 | // Swallow — not every project has a graph. |
| 1439 | } |
no outgoing calls