Skip to content

OpenCode Desktop — Idle Stall Guard + Plugin Loading Fixes

Choose a tag to compare

@kianwoon kianwoon released this 30 Aug 14:07

OpenCode Desktop — Idle Stall Guard + Plugin Loading Fixes

Follows v1.18.25-fork.3 · Commits 3f3475a5d8..a0cdd60d24

This release makes silent provider stalls self-healing and fixes npm plugin
loading in the desktop app. It contains all harness enhancements from
fork.1, fork.2 and fork.3.

New in This Build

⏱️ Idle Stall Guard — default ON (opencode)

Provider streams that go silently silent mid-turn no longer park a session
forever (observed: z.ai GLM gateway held a session 15+ minutes with zero
chunks and zero log lines):

  • Idle guard default ON at 180s for both phases — guards response
    headers and gaps between streamed chunks. It never limits total
    request duration: long healthy reasoning turns are untouchable.
  • ProviderChunkStallError — a distinct, diagnosable error carrying the
    idle window, mapped to a retryable API error and recovered by the
    existing bounded retry schedule (5 attempts, backoff). No manual
    intervention needed.
  • Stall diagnostics — stalls log as WARN with stallIdleMs (stall is
    provider health, not a generic stream failure).
  • Per-provider escape hatches, each phase independently: timeout: false
    (both guards), chunkTimeout: false (chunk guard only),
    headerTimeout: false (headers guard only). Explicit values always win.

🔌 npm plugin entrypoints fixed (core)

The Node branch of plugin entry resolution passed the package directory to
import.meta.resolve, which returns the directory URL verbatim — every
import() of it failed with "Directory import is not supported". This broke
npm plugins (e.g. @zenobius/opencode-skillful) in the desktop Node sidecar
while the Bun CLI worked fine, hiding the bug. Entrypoints now resolve from
the installed package.json (exports["."] → main → index.js), never the
bare name (Bun global-cache shadowing) and never the directory.

Also: the task-effort-router plugin re-export now carries an explicit
.ts extension — the sidecar's Node ESM type-stripping does not do
extensionless resolution.

🖥️ App

  • Running/pending session status shown on titlebar tabs
  • Plugins and skills settings split with per-skill toggles and a skill add flow
  • Provider options.timeout is now strictly idle-based (headers +
    inter-chunk gaps), never a whole-request deadline — long reasoning turns
    cannot be killed mid-flight by a timer

Artifacts

Unsigned mac-arm64 build (same as previous releases). Verified:
channel prod embedded, opencode.db database, server bundle contains the
stall guard and plugin fixes.