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-proxies

v1.0.0

Published

OpenCode v2 plugin for routing model HTTP requests through configurable forward proxies.

Readme

opencode-proxies

Route OpenCode v2 model HTTP requests through configurable forward proxies, including Cloudflare WARP's local HTTP proxy. Give each destination or provider its own proxy using plugin options.

Features

  • Multiple ordered routes, each with a proxy URL and destination URL prefixes.
  • Optional provider filters and subdomain matching.
  • HTTP and HTTPS forward proxies, including proxy URL authentication; HTTPS destinations use CONNECT tunnels.
  • Preserves methods, paths, query strings, request bodies, provider credentials, response status, and streaming responses.
  • Redirects stay on the selected proxy; cross-origin redirects strip authorization and cookies.
  • Unmatched requests retain OpenCode's normal transport. Proxy failures return an error without a direct fallback.
  • No WARP-specific environment variables or hard-coded destinations.

Package 1.0.0 targets OpenCode v2, depends on @opencode/[email protected], and uses the stable plugin ID opencode-proxies. Use Node.js 24+ or a compatible Bun runtime (verification runs on both).

Install and configure

After publication, add this entry to ~/.config/opencode/opencode.jsonc or your project's opencode.json. Append it to your existing plugins array if you have other plugins.

{
  "$schema": "https://opencode.ai/config.json",
  "plugins": [
    {
      "package": "[email protected]",
      "options": {
        "enabled": true,
        "routes": [
          {
            "proxyUrl": "http://127.0.0.1:40000",
            "urls": ["https://opencode.ai"],
            "includeSubdomains": true,
            "providerIds": ["opencode", "opencode-go"]
          }
        ]
      }
    }
  ]
}

This reproduces the routing of zen-warp.ts: Zen and Go requests to opencode.ai and its subdomains go through WARP's local HTTP proxy. WARP must already be running in proxy mode on port 40000; the plugin does not launch or configure it.

OpenCode installs published npm plugins automatically. Quit and restart OpenCode after installing or changing options. Restart its persistent background server too, when applicable.

Options

| Option | Type | Default | Description | | --- | --- | --- | --- | | enabled | boolean | true | false disables routing without starting a relay or registering hooks. | | routes | array | [] | Ordered routes. The first matching route wins. | | routes[].proxyUrl | string | required | Absolute HTTP/HTTPS forward proxy URL, optionally with username/password. Paths, queries, and fragments are not supported. | | routes[].urls | string[] | required | Non-empty list of absolute HTTP/HTTPS destination prefixes. Credentials, queries, and fragments are not supported in these matchers. | | routes[].includeSubdomains | boolean | false | Also match subdomains of each destination hostname. | | routes[].providerIds | string[] | any provider | Optional non-empty list of exact provider IDs. |

Options are read from ctx.options and captured during setup. Invalid options fail setup with a field-specific error that excludes supplied values. An explicitly disabled plugin ignores route configuration. No routes means no listener and no hooks.

TypeScript consumers can import ProxiesOptions and ProxyRoute from opencode-proxies.

URL matching

Matching compares parsed scheme, hostname, port, and path. A prefix of https://api.example.com/v1 matches /v1, /v1/, and /v1/chat?stream=true; it does not match /v10, HTTP, another port, or api.example.com.evil.test. A root URL matches every path on that origin. Trailing slashes on a configured prefix are ignored. Hostname case and default ports are normalized by the URL parser; paths remain case-sensitive and percent-encoded. Query strings on actual requests do not affect matching and are forwarded intact.

includeSubdomains: true matches the exact hostname and dot-separated subdomains, with the same scheme and port. URL prefixes are literal, not glob patterns. Provider and URL conditions must both match.

Multiple proxies and environment substitution

Put specific routes before broader routes:

{
  "$schema": "https://opencode.ai/config.json",
  "plugins": [
    {
      "package": "[email protected]",
      "options": {
        "routes": [
          {
            "proxyUrl": "{env:CORPORATE_PROXY_URL}",
            "urls": ["https://api.example.com/v1/private"],
            "providerIds": ["acme"]
          },
          {
            "proxyUrl": "http://127.0.0.1:40000",
            "urls": ["https://api.example.com/v1", "https://opencode.ai"]
          }
        ]
      }
    }
  ]
}

OpenCode resolves {env:...} before passing options to the plugin. Set variables in the environment of the OpenCode server. An unset URL variable resolves to an empty string and causes validation to fail. An authenticated proxy URL can look like http://username:[email protected]:8080; percent-encode reserved characters in credentials. Diagnostics do not print URLs or credentials.

How the v2 relay works

V2's public http.request hook can replace a standard Request, but cannot set a forward proxy or inject a fetch implementation. The plugin starts an in-process HTTP relay on 127.0.0.1 with an ephemeral port and a random access token, then rewrites matching requests to that relay. Undici's ProxyAgent forwards them through the configured proxy. This uses the public plugin API without patching global fetch or OpenCode internals.

The relay forwards raw response bytes and removes hop-by-hop headers. Model response streams are not buffered. OpenCode's own HTTP-hook adapter may buffer request bodies. Redirect locations are rewritten through the relay so automatic redirects cannot bypass the selected proxy, including when the destination no longer matches the original route. Cross-origin redirects permanently strip authorization and cookie headers for that redirect chain. OpenCode's HTTP client controls redirect limits and method changes.

Client cancellation aborts the upstream request. Unloading disposes registrations, aborts active requests, destroys proxy connection pools, and closes the relay. A proxy failure before response headers produces a redacted HTTP 502; a failure midstream terminates that stream. OpenCode retains control of retries and model timeouts.

Scope

  • Covers native model HTTP requests issued by sessions: primary, title, compaction, and session-generation requests.
  • Does not proxy tool traffic, MCP, package installation, authentication flows, or standalone ctx.generate.text() calls outside the session HTTP hook.
  • OpenCode disables WebSocket optimization for providers with an HTTP hook. If every route has provider filters, this plugin scopes its registrations to those providers. Any unfiltered route requires a global HTTP hook.
  • Proxy endpoints must support HTTP CONNECT. SOCKS proxy URLs and API base-URL rewriting are not supported.
  • Requests that do not match retain any proxy behavior already configured by OpenCode or the environment.

Migrate from zen-warp.ts

  1. Upgrade OpenCode to v2.
  2. Add the package entry and WARP options shown above.
  3. Move ~/.config/opencode/plugin/zen-warp.ts outside the auto-discovered plugin/ and plugins/ directories, and remove an explicit old entry if present.
  4. Replace ZEN_WARP_PROXY with proxyUrl (or "{env:ZEN_WARP_PROXY}" if keeping that variable). Replace its off/disabled values with enabled: false.
  5. Quit and restart OpenCode and its background server. Confirm opencode-proxies and its source in the active plugin list, then exercise a Zen or Go request with WARP connected.

The old @opencode-ai/plugin config-hook implementation is not compatible with v2. Native v2 config uses plugins and { package, options } objects. At implementation time, the shared https://opencode.ai/config.json still described the v1 plugin field; the v2 documentation and released API define the format used here.

Development and verification

Requires Bun, Node.js 24+, npm, and OpenSSL for the temporary HTTPS test certificate.

bun install
bun run check:ci
bun run typecheck
bun run knip
bun run test:coverage
bun run build
bun run test:package

Unit tests cover option validation, matching, provider scoping, request kinds, and registration rollback/cleanup. test:package packs and installs the actual release into an isolated consumer. It resolves and loads the plugin through @opencode/plugin/host, then runs real HTTP and HTTPS CONNECT tests in both Node and Bun: route precedence, proxy authentication, forwarding, redirects, compression, SSE streaming, errors, cancellation, and unload. It also verifies the exact tarball contents and installed public declarations. All traffic stays on local test servers; HTTPS uses a generated trusted test certificate rather than disabling TLS verification.

For local OpenCode testing, run bun run build and set the plugin entry's package to /absolute/path/to/opencode-proxies/dist, the directory containing index.js. Configure routes, restart OpenCode and its background server, and confirm the plugin's ID/source before sending a model request.

Publishing

The npm tarball contains only dist/index.js, index.d.ts, package.json, README.md, and LICENSE. prepack rebuilds JavaScript before packing or publishing.

First release

Run the verification commands above, then:

npm login
npm publish --access public

Subsequent releases

Configure an npm trusted publisher in the package settings:

  • Provider: GitHub Actions
  • Organization/user: ysm-dev
  • Repository: opencode-proxies
  • Workflow filename: publish.yml
  • Environment: leave blank

Bump package.json's version and update the pinned installation examples. Push release changes to main. The workflow verifies the package, publishes unpublished versions with npm provenance through OIDC, and creates a GitHub release. It also supports manual dispatch and skips versions already on npm. No NPM_TOKEN is needed. Complete the first manual publish and trusted-publisher setup before relying on automatic publication.

References and license

MIT — see LICENSE.