Skip to content

fix(ai-hook): support OpenCode v2 plugin lifecycle - #298

Merged
Kuddev merged 18 commits into
Kuddev:mainfrom
WilliamWang1721:fix/opencode-v2-hook
Sep 29, 2026
Merged

Kuddev merged 18 commits into
Kuddev:mainfrom
WilliamWang1721:fix/opencode-v2-hook

Conversation

@WilliamWang1721

@WilliamWang1721 WilliamWang1721 commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Result / 用户结果
Fixes #297.
The generated OpenCode bridge now exposes the default plugin definition required by V2. Its setup adapter translates V2 execution, permission, tool and deletion events into the existing Pebrel notification lifecycle. The V1 implementation remains available through server for OpenCode 1.18.29 and newer.
The failure is confirmed against upstream d60ac70: the installed source has no default export, whereas OpenCode v2.0.18's loader requires default.id and default.setup or default.effect. A real ESM-import regression fails on that source and passes after this change.
Design / 设计边界

  • Responsibility: one embedded hook template, its existing regression suite, and a focused Node/Bun workflow. The Windows and SSH installers continue to consume the same template; ownership checks, filenames and installation policy are unchanged.
  • Reuse: preserve the existing turn reducer, per-session deduplication, permission context, ordering metadata and helper wire format. Observe permission.asked rather than changing permission-evaluation decisions.
  • Lifetime: use built-in node:child_process.execFile without a shell. Keep serialized delivery and the independent three-second watchdog; add subprocess cancellation, timer cleanup and subscription disposal. No runtime package dependency, persistence format or application threading change.
  • Compatibility: the single { id, server, setup } export follows OpenCode's documented dual-version entrypoint. OpenCode versions older than 1.18.29 must upgrade before using this template. V2 events without an envelope location are accepted because OpenCode routes them by session ownership; explicitly foreign locations are ignored.
    Evidence / 验证依据
  • Fork CI — Linux, Windows and macOS: all three jobs succeeded. Each runs the bridge suite under Node 22 and Bun 1.4.2, matching the Bun version in OpenCode v2.0.18.
  • node --test scripts/tests/opencode-notification-bridge.test.mjs: 18 passed locally. Coverage includes actual ESM loading, V1 behavior, V2 event envelopes, permission context, interleaved sessions, cancellation, disposal, stream/helper failures and a real helper-process round trip with literal shell metacharacters.
  • Relevant Python suites: 101 passed — 17 remote-hook/Git-attribute tests and 84 architecture/CI-contract tests.
  • python3 scripts/check_architecture.py --base upstream-snapshot: passed. The snapshot was reconstructed from the Actions-produced upstream ZIP; its Git tree exactly matches upstream d60ac70. The final local tree also exactly matches the pushed tree.
  • git diff --cached --check: passed. Three changed files; production hook changes are +79/-10. No budgets or existing checks were weakened.
  • Review pass 1: checked the pinned V1.18.29 and V2.0.18 loaders, event schemas and bus routing; corrected the initially over-strict location filter and added its regression.
  • Review pass 2: checked helper argument isolation, bounded delivery, disposal and fork permissions; retained the independent watchdog and added both a stuck-callback regression and real-process coverage.
  • Not claimed: full native Rust workspace/UI/SSH end-to-end validation was not run locally; the sandbox has no Rust toolchain. The upstream PR's native matrix remains a separate check. No UI layout or translation changes.
    References: OpenCode migration guide, v2.0.18 loader, V2 session events, V2 bus routing, v2.0.18 event.subscribe signature.
    Required Review / 必须确认
  • I followed CONTRIBUTING.md, docs/architecture.md, and docs/project-constraints.md.
  • Responsibilities remain focused; no duplicate notification-state authority was added.
  • Architecture checks pass against an exact upstream-base tree; budgets were not inflated.
  • Tests cover success and failure; platform and end-to-end limitations are stated.
  • No new user-facing messages or i18n placeholders.
  • No governance-policy change; the workflow adds regression execution without weakening existing gates.
    These checks do not replace maintainer review or the upstream native CI results. Post-sync snapshot for head 241ede06d7446242036efa3455cd86df032f857c (base 77e6470a9d1c938b9ee044df90f5524bf6d0d505): pr-size passed; architecture-contracts, lint, and the Linux, Windows, and macOS OpenCode bridge jobs were pending. Native Tests jobs were not reported in this snapshot. See live PR checks.

AI assistance for this review and follow-up: GPT-6 Luna (max reasoning effort). Earlier implementation model metadata is unavailable in this continuation.

Use a single default definition with V1.18.29+ server and V2 setup entries.
Adapt durable V2 execution and permission events to the existing bridge,
including unlocated session events. Keep serialized, bounded, shell-free
helper delivery and dispose owned subscriptions and processes.

Add regression coverage and Node/Bun CI on Linux, Windows and macOS.

Fixes Kuddev#297
Kuddev
Kuddev previously approved these changes Sep 27, 2026

@Kuddev Kuddev left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review 结论:未发现阻塞项。已核对 OpenCode v1.18.29 的 server 入口、v2.0.18 默认导出校验/事件 schema/按 location 路由,检查单一导出、turn 去重、permission 上下文、无 shell 的 helper 调用、3 秒超时与独立 watchdog、AbortController/计时器/订阅清理。现有串行发送和最多 512 个会话的边界保留;没有新增 Pebrel 常驻线程、轮询或终端绘制开销。已在隔离 worktree 的本次精确 head 上运行 node --test scripts/tests/opencode-notification-bridge.test.mjs:Node 24.13.0,18/18 通过,含真实 helper 进程参数往返。Bun/Node 22 和其他平台结果以 PR CI 为准;未重跑完整 OpenCode UI/SSH 端到端。合并前仍需在最新 main 上通过全部必需检查。

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Fix the subscription API usage and undefined test helper, align the test double, and add the required architecture note.

Review effort: Lite
Findings: 2 High severity · 1 Low severity

Open (3)
What changed in this PR

Adds OpenCode V2 plugin lifecycle support while preserving V1 compatibility.

Changes:

  • Adds dual-version plugin exports and event translation.
  • Improves subprocess cancellation and cleanup.
  • Adds Node/Bun regression tests and cross-platform CI.
File Summary
scripts/​tests/​opencode-notification-bridge.test.mjs V1/V2 lifecycle and helper regression tests
nebula_app/​res/​hooks/​opencode.js Dual-version bridge and lifecycle handling
.github/​workflows/​opencode-bridge.yml Node/Bun tests across platforms

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread nebula_app/res/hooks/opencode.js
Comment thread scripts/tests/opencode-notification-bridge.test.mjs
Comment thread nebula_app/res/hooks/opencode.js

@Kuddev Kuddev left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified the V2 default plugin definition and single-argument event.subscribe API against the official OpenCode v2.0.18 sources. Reviewed the shared V1/V2 adapter, serialized helper delivery, timeout and cleanup ownership. All 18 Node bridge regressions pass locally, including the real helper process and literal argument delivery.

@Kuddev
Kuddev merged commit 2bddb99 into Kuddev:main Sep 29, 2026
14 checks passed
@WilliamWang1721
WilliamWang1721 deleted the fix/opencode-v2-hook branch September 30, 2026 03:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] OpenCode 2.x 下自动生成的 opencode hook 使用 V1 插件 API,导致插件加载失败(Missing default export)

3 participants