DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

Opencode Go Catalog — DSH Plugin for DeepSeek Harness
← Plugins
O

dsh-opencode-go-catalog

Opencode Go Catalog

Live-maintained OpenCode Go model catalog for DeepSeek Harness: protocol-separated sibling routes (extras/responses/messages) via the settings.mutate seam. Membership is rebuilt from the live roster plus the docs endpoint table on every sync, so new models appear and retired ones drop out without ha

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:AincradLabs/dsh-opencode-go-catalog#1a14870759efed992aca7832088fa9765327f061
READMECompatibilityVersions

Description

Live-maintained OpenCode Go model catalog for DeepSeek Harness: protocol-separated sibling routes (extras/responses/messages) via the settings.mutate seam. Membership is rebuilt from the live roster plus the docs endpoint table on every sync, so new models appear and retired ones drop out without hand work. Never touches the built-in opencode-go route.

Compatibility and provenance

Opencode Go Catalog is published as dsh-opencode-go-catalog and currently resolves to version 0.2.0. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
any
Release source
github
Registry updated
10/13/2026

Versions

0.2.0stable
10/13/2026
0.1.4stable
10/11/2026
0.1.2stable
10/11/2026

Related plugins

Loading related plugins…

Latest
0.2.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
any
License
MIT
Source
github
GitHub
★ 0
Weekly downloads
0
Last push
10/13/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in

Related plugins

More verified plugins in models-usage.

Whale Widgetdsh-whale-widgetDeepSeek balance whale widget in the bottom-right corner of the DSH Web interface: balance/today’s usage/peak-off-peak pricing, customizable bubble click sequence (text/balance/today/peak-off-peak/image/random phrases and parallel weighted selection), per-line styles and fonts, floating quick editinUsage@linxin666/dsh-usageUsage statistics plugin for the dsh web GUI: per-provider balance and coding-plan quota detection plus a live token usage ledger, with a compact price glance card above the sidebar's Settings rowClient Ui Model Capabilities@linxin666/dsh-client-ui-model-capabilitiesPer-model capability declarations (image input and reasoning efforts) for custom pi-ai providers, edited in place on the Models settings cards; writes the official llm-pi-ai settings namespace, no DSH source changes.Cost Meterdsh-cost-meterDeepSeek Harness session cost statistics plugin: current session cost, today’s charges, historical records, and synchronization with official pricing; supports multi-provider, multi-model price calculation (built-in pricing catalog for 170+ model IDs with automatic matching); queries and displays su

README

dsh-opencode-go-catalog

A live-maintained OpenCode Go model catalog for DeepSeek Harness (DSH). Membership is rebuilt from the live roster plus the docs endpoint table on every sync — new models appear, retired ones drop out, no hand work. A curated snapshot stays as the offline fallback.

Status: 0.2.0 · auto membership · 33 models live (2026-10-13), incl. Cat Jam Free (cat-jam-free)

Contents

  • Why
  • How it works
  • Installation
  • Configuration
  • Commands & scripts
  • Fresh reasoning efforts
  • The protocol oracle
  • Maintaining the catalog
  • Enable / disable
  • Troubleshooting
  • Security
  • Compatibility
  • License & sources

Why

The built-in opencode-go route of @deepseek-ai/dsh-llm-pi-ai serves a static catalog shipped in @earendil-works/pi-ai (30 models at the time of writing) that never refreshes itself — new models like Step 5 or Cat Jam are missing until upstream bumps the dependency. See Discussion #3957.

This plugin never touches the built-in route. It manages three sibling routes through the official settings.mutate seam:

RouteProtocolExamples
opencode-go-extrasopenai-completionsCat Jam Free, Step 5 Preview Free, GLM-5.3, LongCat, MiMo, Kimi, DeepSeek
opencode-go-responsesopenai-responsesGPT-5.6/6 Luna, Grok 4.6/4.7, Muse Spark 1.2/1.3
opencode-go-messagesanthropic-messagesClaude Haiku 5.5, Qwen3.8, MiniMax M2.7/M3

The split is mandatory, not stylistic: some Go models are Responses-only (a chat-completions request answers with a bare 500 or 401 "not supported for format oa-compat"), others are Messages-only. One route = one protocol.

Why not put the extra models on the built-in route? Source-verified against dsh-llm-pi-ai: resolveRouteModels computes a model's protocol as request.api ?? base?.api ?? routeApi — an api field on a model entry is never read. A model the shipped catalog does not describe therefore needs the route-level api, and setting that routes opencode-go through createProvider() over a single protocol (the catalog provider is only reused while spec.api === undefined), losing both the three-protocol dispatch and pi-ai's session-header wrapper. On top of that, any models list replaces the served catalog. The built-in route stays untouched.

How it works

  1. Registry — https://models.opencode.ai/api.json (keyless, ETag cache + last-good fallback) supplies name, limits, input modalities, and reasoning_options per model.

  2. Roster — https://opencode.ai/zen/go/v1/models (keyless) says which IDs exist right now.

  3. Protocol oracle — https://opencode.ai/docs/go/ carries an endpoint table per model ID (…/go/v1/chat/completions, /responses, /messages). See The protocol oracle.

  4. Membership is then roster ∩ registry ∩ protocol-known, minus the veto list. On startup, on an interval (default 4 h), and on /opencode-go-sync the three sibling routes are written via settings.mutate.

  5. Fail-safe. The auto mode refuses to write, and the curated snapshot in catalog/models.json is served unchanged, when

    • the roster or the oracle is unavailable (network, docs redesign), or
    • fewer than minAutoModels models resolve, or
    • fewer than minAutoRatio (default 60 %) of the last adopted set resolve — this catches a degraded source that would otherwise quietly empty half the picker and stamp the missing IDs as retired.

    A single route that comes out empty is not fatal either: llm-pi-ai rejects a route with resolves no models, and because all three routes go into one settings.mutate, one empty group would block the healthy groups too — so that route is served from the snapshot and reported in status.json (auto.snapshotRoutes). A network outage or a docs redesign can therefore never empty the picker. Missing capacities are never invented — the field is omitted and needsReview is reported, so llm-pi-ai applies its own route defaults (262144 / 32768).

  6. The module never throws during boot, never edits node_modules, and never reads or writes credentials (it only references the OPENCODE_GO_API_KEY name, same as the built-in route).

Hand-added models do not survive. settings.mutate persists into the profile's cordis.patch.yml, and each sibling route is written as one whole object. A model you add by hand (or via Settings → Models → Fetch available models → Add model) inside one of these three routes is gone at the next sync — startup, interval, or /opencode-go-sync. Durable entries belong in the snapshot (node bin/sync.mjs --adopt) or in the veto list.

Installation

Prerequisites: DSH running, an OpenCode Go subscription with a working key (OPENCODE_GO_API_KEY already configured — if the built-in opencode-go route works, you are set).

Via Plugin Market (once listed): Settings → Plugin Market → search dsh-opencode-go-catalog → one-click install → restart → open the model picker. Expect three new groups (OpenCode Go extras / responses / messages) next to the built-in one.

Manual: copy this folder to <profile>/node_modules/dsh-opencode-go-catalog, add "dsh-opencode-go-catalog" to dsh.profile.bundles in the profile package.json (keep a backup first), restart DSH.

Without the plugin (static, no auto-refresh): generate the snippet and replace your llm-pi-ai row with it — see INSTALL.md and weg-a-schnellstart.yml:

node bin/snippet.mjs > snippet.yml

Configuration

Bundle row (cordis.patch.yml, replaces the whole row — no deep merge):

- id: opencode-go-catalog
  name: dsh-opencode-go-catalog
  config:
    enabled: true            # false → sibling routes are removed again
    autoMembership: true     # false → curated snapshot only, no roster/oracle
    minAutoModels: 8         # safety belt: below this the snapshot is served
    minProtocolRows: 10      # safety belt against a docs redesign
    minAutoRatio: 0.6        # safety belt against a degraded (not dead) source; 0 disables it
    refreshReasoning: true   # false → snapshot values only, no network (this also disables auto mode)
    sessionHeaderValue: 'dsh-opencode-go-catalog'  # false → no static session header (400 risk)
    intervalMinutes: 240     # 0 → startup only
    startupDelaySeconds: 10
    refreshTimeoutMs: 120000
    catalogPath: ./catalog/models.json
    managedRoutes:
      - opencode-go-extras
      - opencode-go-responses
      - opencode-go-messages

Commands & scripts

CommandEffect
/opencode-go-sync (chat)Immediate rewrite from the live sources. Registered through ctx.root into the global command layer, so it appears in the / menu for every session (registering through the plugin fiber context lands outside all agent scope chains: self-probe green, menu empty — fixed in 0.1.4)
node bin/sync.mjs (default)Report: field diffs, new live IDs with their protocol, dead IDs — writes nothing
node bin/sync.mjs --autoPreview what the auto mode would publish (per route, added, removed, unresolved). Uses the default safety belts — a non-default minAutoModels/minAutoRatio/minProtocolRows in the profile patch can make the host decide differently
node bin/sync.mjs --adoptWrite the live membership into the snapshot (fallback stays current)
node bin/sync.mjs --writeRewrite snapshot fields from the registry + stamp the date
node bin/sync.mjs --checkOffline snapshot rule check
node bin/snippet.mjsPrint the complete llm-pi-ai replacement row for manual installs
node verify.mjsManifest + patch shape + catalog rules + fixture tests for oracle and auto builder (offline)

Fresh reasoning efforts

reasoning_options in the live registry are structured (effort values, toggle, budget_tokens) — Models.dev serves the same data. Mapping rules (lib/reasoning.mjs):

Registrypi-ai reasoningEfforts
effort values (low, medium, …)Identity mapping (low: low, …)
none valueoff: none
toggle-only / budget_tokens-only / empty arrayno block (never invent a menu — the picker would lie)
toggle + effort combinedeffort wins
modalities.input containing imageinput: [text, image] (pi-ai only knows text/image; video/audio/pdf are dropped documented)

Live examples: Cat Jam Free → {low, medium, high, xhigh, max}; GPT-5.6 Luna → {off: none, low…max}; Muse Spark → {minimal…xhigh} (no max!); LongCat-2.0 / MiniMax M3 (toggle-only) → no menu.

The protocol oracle

No JSON endpoint discloses the wire protocol. The docs endpoint table does, per model ID, and it is the same table the hand-calibrated snapshot was verified against:

SourceVerdict
https://opencode.ai/docs/go/ endpoint tableoracle — 33 rows on 2026-10-13
Hand-calibrated snapshot0 conflicts with the table
Shipped pi-ai catalog (data/opencode-go.json)not usable — contradicts the table on minimax-m2.7, qwen3.7-plus, qwen3.8-max

lib/protocols.mjs parses the table (htmlToText + one row regex) and filters every hit against the live roster, so a regex false positive can never invent a model ID. An ID without a table row is not guessed — it is reported as unresolved in status.json and stays out. Current examples: qwen3.6-plus, qwen3.7-max (live and in the registry, but undocumented), deepseek-flash, glm-5.1, omen-alpha (roster-only, no metadata at all).

If the page stops yielding at least minProtocolRows rows, the last-good cached table is used; only without a cache does the snapshot apply. A row that contradicts another row for the same ID takes that ID out of the oracle entirely (keeping the first would be a guess) and is reported under auto.conflicts in status.json.

Maintaining the catalog

Normally nothing: the auto mode is the maintenance. The snapshot only needs attention when you want to pin something or keep the fallback current:

  1. node bin/sync.mjs --auto — see what the live sources currently produce.
  2. node bin/sync.mjs --adopt — take the live membership into catalog/models.json (also moves vanished IDs into retired). Run it after a model appears or disappears, so an offline start serves the same list.
  3. To keep a live model out of the picker, list it in excluded with a reason.
  4. node verify.mjs → /opencode-go-sync.

Enable / disable

  • Siblings off, plugin stays loaded: add your own - id: opencode-go-catalog row (with the FULL config — patches replace, never merge; copy cordis.patch.yml as the template) to your profile patch with enabled: false. The three routes are removed again via unset ops; the built-in opencode-go route keeps running untouched.
  • Auto mode off, curated snapshot on: autoMembership: false.
  • Whole plugin off: disabled: true on the bundle row (or the market's disable list), restart. Nothing needs deleting.

Session header (MissingSessionID-400)

OpenCode Go requires x-opencode-session (stable per-conversation ID) since 09/05 — see Discussion #5495.

Refined 2026-10-13, source-verified: dsh-llm-pi-ai does forward a per-conversation id (…options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) }), and pi-ai's catalog provider wraps its APIs with withOpenCodeSessionHeader, which reads exactly that sessionId. The gap is narrower than "the adapter has no sessionHeader": hand-declared routes never pass through that wrapper, because createProvider calls the raw protocol factory. So a sibling route still needs the static header below.

Until a declared route can opt into the wrapper, this plugin sets a static header on every sibling route (sessionHeaderValue, default 'dsh-opencode-go-catalog', off with false). Trade-off, stated plainly: one fixed ID across all conversations means fewer cache hits — slower and pricier than a proper per-conversation ID (user-verified). It beats a hard 400. The built-in opencode-go route is never touched (it gets the real per-conversation header from pi-ai itself). Upstream: earendil-works/pi#9326 — the ask is "apply withOpenCodeSessionHeader to declared routes too", not "add sessionId to the adapter".

Diagnostics

After every sync attempt the plugin writes status.json next to package.json (time, ok, via, changed, command, fetch, error, and for auto mode: roster/protocols source, members, perRoute, added, removed, unresolved, vetoed, needsReview). Open it in any editor — no log access needed. If the picker stays empty, send this file's content with your report.

Troubleshooting

SymptomCauseFix
New model missing from the pickerNot in the roster, or no protocol row in the docs tableCheck status.json → auto.unresolved; a live-but-undocumented model needs a probe before it can be adopted
Model disappeared after a restartIt was added by hand to one of the three managed routesDurable entries go into the snapshot (--adopt) or the veto list
Model answers 500 / 401 not supported for formatWrong protocol (e.g. a Responses-only model on a completions route)Fix the oracle source or move it in the snapshot; --auto shows the current assignment
Picker suddenly much smallerRoster/oracle unreachable and the snapshot is stalestatus.json → fetch/auto; run node bin/sync.mjs --adopt while online
model '…' needs an apiHand-declared route without apiSet api + baseURL + non-empty models (the plugin does this automatically)
Images rejected before sendinginput is [text]Set input: [text, image] per model (only with proven vision support)
No effort menureasoningEfforts missingAdopt from the registry's reasoning_options; mind off: none vs empty off
400 MissingSessionIDGateway needs x-opencode-session, declared routes get no wrapperPlugin sets a static one per sibling route (see above)
Installed but seemingly idle—This plugin uses no shell hooks; check status.json next to package.json
Install gate refusesPeer range with stable lower boundNot applicable here (no @deepseek-ai/dsh* peers declared on purpose)

Never hand-edit node_modules/…/pi-ai/dist/providers/data/opencode-go.json — the next DSH update discards it silently. This snapshot is the place.

Security

  • No secrets: the plugin never reads, writes, logs, or ships credentials. OPENCODE_GO_API_KEY appears only as a name reference, exactly like the built-in route. Verified by pre-commit sweep.
  • Network: only three public, keyless endpoints (models.opencode.ai/api.json, opencode.ai/zen/go/v1/models, opencode.ai/docs/go/), each with timeout + cache + offline fallback to snapshot values.
  • Zero dependencies, no @deepseek-ai/dsh* peers (the install gate cannot refuse it), no shell hooks, fail-safe boot.

Compatibility

Built against DSH 0.2.0-rc.2 behavior (static pi-ai catalog, settings.mutate seam, optional command registry). Pure ESM, Node ≥ 18.

License & sources

MIT — see LICENSE.

  • Go | OpenCode (model list + endpoint table)
  • OpenCode Go on Models.dev (context/output/pricing)
  • Step 5 Preview · Step 5 API docs
  • Discussion #3957 (stale-catalog root cause)
  • Discussion #5495 (session header)
  • Plugin authoring (dsh.pub) · Config & publishing
  • Live roster: https://opencode.ai/zen/go/v1/models · Registry: https://models.opencode.ai/api.json