npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

opencode-cpa-provider

v0.1.0

Published

Metadata-aware CLIProxyAPI provider for OpenCode v2

Readme

OpenCode v2 CLIProxyAPI provider

Personal-use provider plugin built from scratch for OpenCode v2. Discovers CPA's served models and uses OpenCode's native OpenAI-compatible runtime for inference. No management key, upstream authentication or existing discovery plugin code.

Load

cd /mnt/media/Git/opencode-cpa-provider
bun install
git config --local core.hooksPath .githooks

Remove your old discovery plugin from plugins, then add this entry to your OpenCode configuration. Keep unrelated plugins and settings. This repository does not modify your live configuration.

{
  "$schema": "https://opencode.ai/config.json",
  "plugins": [
    {
      "package": "/mnt/media/Git/opencode-cpa-provider",
      "options": {
        "baseURL": "http://192.168.1.1:8317/v1",
        "apiKeyEnv": "CPA_API_KEY",
      },
    },
  ],
}

Set CPA_API_KEY in the OpenCode server's environment if CPA requires a client key. No key is needed for an unauthenticated endpoint. Restart/reload OpenCode, then select cpa/<advertised-id> in /models. Namespaced and ~ IDs are preserved. Discovery runs in the background; the initial list may take a few seconds.

To keep your current provider prefix (and saved selections), set providerID to that prefix instead of cpa. Existing providers.<id> settings and explicitly defined models take precedence over discovered defaults. Old static models remain until you remove them from configuration, even if CPA stops advertising them.

Provider settings are also the place for custom headers, model overrides or a Responses runtime:

{
  "providers": {
    "cpa": {
      "settings": {
        "baseURL": "http://192.168.1.1:8317/v1",
        "apiKey": "{env:CPA_API_KEY}",
      },
      "models": {
        "unusual-model": {
          "limit": { "context": 131072, "output": 8192 },
          "capabilities": { "tools": true, "input": ["text"], "output": ["text"] },
        },
      },
    },
  },
}

Metadata

Works with or without /mnt/media/Git/cpa-plugin-model-context installed in CPA. It reads ordinary /v1/models, not the synthetic Codex catalogue. Both data[].id and models[].slug list formats are accepted.

  • Uses advertised names, family, context/input/output limits, modalities, tool support, release dates and per-million-token prices (including cache prices).
  • Turns thinking.levels, supported_reasoning_levels and effort-type reasoning_options into selectable variants. Explicit false/empty controls win.
  • Advertised budget bounds create numeric variants; zero_allowed adds none and dynamic_allowed adds auto. An advertised toggle also adds none unless native zero_allowed explicitly forbids it. No invented effort names or budgets.
  • Variants send CPA's model(effort) or model(budget) syntax through a raw body overlay. CPA handles the upstream translation. For example, cpa/~vendor/model#max sends ~vendor/model(max).
  • Recognises Chat Completions reasoning_content for streamed reasoning and conversation replay. Override compatibility.reasoningField per model if needed.
  • Bare rows assume text input/output and tool support, with a 32,768 context and 8,192 output limit. These are fallback assumptions, not detected capabilities. Missing vision support is not guessed. Explicit non-text output is excluded.
  • attachment, temperature and structured_output flags have no corresponding v2 model capability field; they do not become unsupported schema extensions. Output limits not emitted by your CPA metadata plugin remain fallback values.

No secondary models.dev/OpenRouter fetches or model-name heuristics are used. The metadata plugin remains the single owner of catalogue matching.

Options

| Option | Default | Meaning | | ------------------- | -------------------------- | ------------------------------------------------ | | providerID | cpa | OpenCode provider/model prefix | | baseURL | http://127.0.0.1:8317/v1 | CPA API URL; root URLs get /v1 appended | | apiKeyEnv | CPA_API_KEY | Client key environment variable name | | refreshIntervalMs | 60000 | Inventory refresh interval; 0 disables polling | | timeoutMs | 5000 | Discovery deadline | | fallbackContext | 32768 | Context when no positive limit is advertised | | fallbackOutput | 8192 | Output when no positive limit is advertised | | assumeTools | true | Tool support when CPA supplies no explicit flag |

Provider settings.baseURL takes precedence over plugin options. Credentials follow OpenCode's inference precedence: an active connection for integrationID (or the provider ID by default), then settings.apiKey, then the configured environment variable. Account-bound inventory is hidden after switching accounts until refresh succeeds. Discovery uses provider headers and does not follow redirects. API keys and model lists are not stored on disk by this plugin.

Run /cpa-refresh for an immediate refresh. Requests are serialised. A failed or malformed response keeps the last successful inventory; a valid empty list clears discovered models. If CPA is unavailable on first load, only explicit configured models are available until discovery succeeds. Failure messages go to the server log without keys or response bodies.

Local verification

bun run check
bun run lint
bun run smoke
bun run build

The smoke script runs a short in-process fixture server and closes it afterwards. It checks metadata mapping, the refresh lifecycle and a native OpenCode runtime request against a local streaming fixture, including reasoning and variant lowering. It does not call paid upstream models or check upstream model quality. dist/index.js is an optional compiled entrypoint; the local package loads src/index.ts through the root index.ts directory-loader entrypoint. Architecture: docs/design.md.

Linting uses the thea-mode oxlint.config.ts template, including type-aware lint and type checking. Targeted exceptions cover OpenCode's required default export, intentional environment lookup, plain schema-data copying, the captured lifecycle scope and the minimal Bun-only smoke fixture; no blanket lint disable is used.

bunfig.toml, oxfmt.config.ts, tsconfig.json and commitlint.config.ts also use the thea-mode templates. TypeScript's application-specific Vite/Worker types are replaced with Bun types; the strict compiler checks are retained. Formatting sorts imports and package scripts. Bun disables telemetry and applies the template's three-day minimum release age to dependency resolution. Local Git hooks run check before commits and enforce conventional commit messages. bun run lint:commits checks the latest commit independently.