fix(nix): ship the OpenCode v2 bridge plugin in the daemon closure (#5988)

The Nix package copies only what scripts/trace-daemon.mjs lists. The list
named the v1 bridge bundle but not opencode/v2/bridge-plugin.bundle.mjs,
so creating an OpenCode v2 agent from the Nix package failed with
"Bundled OpenCode bridge plugin artifact is missing".

List every bridge bundle under opencode/, and add a dist test that
installs the traced closure the way nix/package.nix does and loads the
bridge plugin for each OpenCode version from it.

Closes #5926

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
This commit is contained in:
paseo-bot[bot]
2026-10-03 23:16:11 +01:00
committed by GitHub
parent 5eb4c8afad
commit ed87679c67
2 changed files with 49 additions and 2 deletions
+46
View File
@@ -0,0 +1,46 @@
import assert from "node:assert/strict";
import { execFile } from "node:child_process";
import { cp, mkdtemp, rm } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import test from "node:test";
import { fileURLToPath, pathToFileURL } from "node:url";
import { promisify } from "node:util";
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const bridgeModule = "packages/server/dist/server/server/agent/providers/opencode/bridge.js";
// Mirrors nix/package.nix's installPhase: copy every traced path into $out.
async function installTracedDaemon(outRoot) {
const { stdout } = await promisify(execFile)(
process.execPath,
[path.join(repoRoot, "scripts/trace-daemon.mjs")],
{ cwd: repoRoot, maxBuffer: 64 * 1024 * 1024 },
);
for (const file of stdout.split("\n").filter(Boolean)) {
await cp(path.join(repoRoot, file), path.join(outRoot, file), {
recursive: true,
verbatimSymlinks: true,
});
}
}
test("traced daemon closure ships the OpenCode bridge plugin for every OpenCode version", async () => {
const outRoot = await mkdtemp(path.join(os.tmpdir(), "trace-daemon-dist-"));
try {
await installTracedDaemon(outRoot);
const installedBridgeUrl = pathToFileURL(path.join(outRoot, bridgeModule)).href;
const { loadOpenCodeBridgePluginArtifact } = await import(installedBridgeUrl);
for (const version of [1, 2]) {
const artifact = await loadOpenCodeBridgePluginArtifact(
installedBridgeUrl,
undefined,
version,
);
assert.ok(artifact.byteLength > 0, `OpenCode v${version} bridge plugin is empty`);
}
} finally {
await rm(outRoot, { recursive: true, force: true });
}
});
+3 -2
View File
@@ -58,8 +58,9 @@ const additionalInputs = [
"packages/server/dist/server/terminal/shell-integration/**",
// Silero VAD ONNX model (sherpa speech provider)
"packages/server/dist/server/server/speech/providers/local/sherpa/assets/silero_vad.onnx",
// OpenCode loads this plugin from a content-addressed runtime copy.
"packages/server/dist/server/server/agent/providers/opencode/bridge-plugin.bundle.mjs",
// OpenCode loads these plugins from a content-addressed runtime copy, one
// bundle per supported OpenCode version (opencode/ and opencode/v2/).
"packages/server/dist/server/server/agent/providers/opencode/**/bridge-plugin.bundle.mjs",
// Server runtime config files (read by path, not require)
"packages/server/.env.example",
// CLI shebang script wrapping dist/index.js