Summary
opencode-companion.mjs setup (and setup --json) always returns an empty providers array, even when OpenCode has providers configured and connected. The handler assumes the GET /provider endpoint returns an array, but current OpenCode returns an object { all, default, connected }. The Array.isArray() guard is therefore always false and providers is never populated.
Environment
Plugin: tasict-opencode-plugin-cc, opencode companion 1.0.0
OpenCode CLI: 1.17.0
OpenCode server API: 1.16.2 / 1.17.0 (both return the object shape)
Node: v20+
OS: Linux
Affected code
scripts/opencode-companion.mjs → handleSetup() (provider detection block), which calls client.listProviders() defined in scripts/lib/opencode-server.mjs:170 as request("GET", "/provider").
Root cause
GET /provider returns:
{
"all": [ { "id": "...", "name": "...", "models": {...} }, ... ], // full catalog of known providers
"default": { "<providerId>": "<defaultModel>", ... },
"connected": [ "zai-coding-plan", "opencode" ] // providers with credentials configured
}
The companion expects a bare array:
const providerList = await client.listProviders();
if (Array.isArray(providerList)) { // ← false: response is an object
providers = providerList.map((p) => p.id ?? p.name).filter(Boolean);
}
Because the response is an object, the branch never executes and providers stays [] regardless of configuration. The list of actually configured/authenticated providers lives in connected.
Steps to reproduce
Configure a provider (e.g. opencode auth login → Z.AI Coding Plan), confirm with opencode providers list / opencode models.
Run node scripts/opencode-companion.mjs setup --json.
Observe "providers": [].
Compare with curl -s http://127.0.0.1:4096/provider → connected clearly lists the configured provider(s).
Expected vs actual
Expected: providers reflects the configured/connected providers (e.g. ["zai-coding-plan", "opencode"]).
Actual: providers is always [].
Proposed fix
Handle the object shape and read from connected (fall back to all for forward/backward compatibility, and keep the array branch for older servers):
const providerList = await client.listProviders();
if (Array.isArray(providerList)) {
providers = providerList.map((p) => p.id ?? p.name).filter(Boolean);
- }
+ } else if (providerList && typeof providerList === "object") {
+ // Newer OpenCode returns { all, default, connected }; the providers
+ // with credentials configured live in `connected`.
+ if (Array.isArray(providerList.connected)) {
+ providers = providerList.connected;
+ } else if (Array.isArray(providerList.all)) {
+ providers = providerList.all.map((p) => p.id ?? p.name).filter(Boolean);
+ }
+ }
After the fix, setup --json correctly reports:
{ "installed": true, "version": "1.17.0", "serverRunning": true, "providers": ["zai-coding-plan", "opencode"], "reviewGate": false }
Additional note (not a plugin bug, but interacts with this)
The companion talks to a hardcoded server at http://127.0.0.1:4096. A long‑lived opencode serve --port 4096 started before new credentials were added will keep reporting a stale connected list (in my case it omitted zai-coding-plan and showed a normalized zai instead). Restarting that server makes it re‑read auth.json and report correctly. Consider either (a) detecting/refreshing a stale server, or (b) documenting that the 4096 server must be restarted after changing OpenCode auth — otherwise the corrected setup output can still look wrong purely due to a stale server process.
Summary
opencode-companion.mjs setup (and setup --json) always returns an empty providers array, even when OpenCode has providers configured and connected. The handler assumes the GET /provider endpoint returns an array, but current OpenCode returns an object { all, default, connected }. The Array.isArray() guard is therefore always false and providers is never populated.
Environment
Plugin: tasict-opencode-plugin-cc, opencode companion 1.0.0
OpenCode CLI: 1.17.0
OpenCode server API: 1.16.2 / 1.17.0 (both return the object shape)
Node: v20+
OS: Linux
Affected code
scripts/opencode-companion.mjs → handleSetup() (provider detection block), which calls client.listProviders() defined in scripts/lib/opencode-server.mjs:170 as request("GET", "/provider").
Root cause
GET /provider returns:
The companion expects a bare array:
Because the response is an object, the branch never executes and providers stays [] regardless of configuration. The list of actually configured/authenticated providers lives in connected.
Steps to reproduce
Configure a provider (e.g. opencode auth login → Z.AI Coding Plan), confirm with opencode providers list / opencode models.
Run node scripts/opencode-companion.mjs setup --json.
Observe "providers": [].
Compare with curl -s http://127.0.0.1:4096/provider → connected clearly lists the configured provider(s).
Expected vs actual
Expected: providers reflects the configured/connected providers (e.g. ["zai-coding-plan", "opencode"]).
Actual: providers is always [].
Proposed fix
Handle the object shape and read from connected (fall back to all for forward/backward compatibility, and keep the array branch for older servers):
After the fix, setup --json correctly reports:
Additional note (not a plugin bug, but interacts with this)
The companion talks to a hardcoded server at http://127.0.0.1:4096. A long‑lived opencode serve --port 4096 started before new credentials were added will keep reporting a stale connected list (in my case it omitted zai-coding-plan and showed a normalized zai instead). Restarting that server makes it re‑read auth.json and report correctly. Consider either (a) detecting/refreshing a stale server, or (b) documenting that the 4096 server must be restarted after changing OpenCode auth — otherwise the corrected setup output can still look wrong purely due to a stale server process.