Official
opencode
OpenCode agent provider: runs opencode serve and talks to it over HTTP and server-sent events.
The app opens the listing; nothing installs until an agent in your Plugins workspace has read the files and you enable the plugin. In a terminal: cvg install convergence/opencode@0.2.0
Permissions in 0.2.0
Files
maintenance.test.ts2.6 KB
import { test } from "node:test";
import assert from "node:assert/strict";
import { describe, npmPrefix, ownerOf, updateCommand } from "./maintenance.ts";
import { fakeApi } from "../sdk/testing.ts";
import { testRuntime } from "./testing.test.ts";
test("the install script's own layout is native", () => {
assert.deepEqual(ownerOf("/Users/dev/.opencode/bin/opencode"), { manager: "native" });
assert.deepEqual(ownerOf("C:\\Users\\dev\\.opencode\\bin\\opencode.exe"), { manager: "native" });
// A path that merely mentions the folder is not the binary.
assert.deepEqual(ownerOf("/Users/dev/.opencode/bin/opencode-helper"), { manager: "" });
// A link on PATH proves as much as the file it points at.
assert.deepEqual(ownerOf("/usr/local/bin/opencode", "/Users/dev/.opencode/bin/opencode"), { manager: "native" });
});
test("a global npm install names its prefix; a project's dependency is not owned", () => {
assert.equal(npmPrefix("/usr/local/lib/node_modules/opencode-ai/bin/opencode"), "/usr/local");
assert.equal(npmPrefix("/opt/homebrew/lib/node_modules/opencode-ai/dist/opencode"), "/opt/homebrew");
assert.equal(npmPrefix("/lib/node_modules/opencode-ai/bin/opencode"), "/");
assert.equal(npmPrefix("/w/app/node_modules/.store/lib/node_modules/opencode-ai/bin/opencode"), null);
assert.equal(npmPrefix("/w/node_modules/opencode-ai/bin/opencode"), null);
assert.equal(npmPrefix("/usr/local/bin/opencode"), null);
// The 2.x CLI is another package, which this plugin does not upgrade.
assert.deepEqual(ownerOf("/u/.local/bin/opencode", "/u/.local/lib/node_modules/@opencode/cli/bin/opencode.exe"), {
manager: "",
});
});
test("update commands match the proven installer", () => {
assert.deepEqual(updateCommand({ manager: "native" }), { program: "opencode", args: ["upgrade"] });
assert.deepEqual(updateCommand({ manager: "npm", prefix: "/usr/local" }), {
program: "npm",
args: ["install", "-g", "--prefix", "/usr/local", "--allow-scripts=opencode-ai", "opencode-ai@latest"],
});
assert.equal(updateCommand({ manager: "" }), null);
});
test("an unproven install reports the version but refuses to update, and asks no registry", async () => {
const api = fakeApi({
onHost: (method) =>
method === "host/process.which" ? { path: "/usr/local/bin/opencode", realPath: "/usr/local/bin/opencode" } : {},
onSpawn: () => new Error("no registry may be asked"),
});
const { run } = testRuntime(api);
const maintenance = await run(describe("1.18.29"));
assert.deepEqual(maintenance, { manager: "", canUpdate: false, installedVersion: "1.18.29" });
});Versions
| Version | Published | Plugin API | Size | Permissions | Status |
|---|---|---|---|---|---|
| 0.2.0latest | Oct 5, 2026 | >=2 <3 | 94.8 KB | 5 permissions | Listed |
No comments yet.