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-devin-auth

v0.4.1

Published

OpenCode plugin for Devin/Cognition authentication — use Devin models in OpenCode

Readme

opencode-windsurf-auth

npm version npm beta npm downloads License: MIT

Use Windsurf models in opencode: Claude, GPT, Gemini, Kimi, DeepSeek, SWE-1.6, and more with your existing Windsurf subscription. All via Windsurf OAuth, no app required.

Install

Option A - one-line wizard (recommended)

curl -fsSL https://raw.githubusercontent.com/rsvedant/opencode-windsurf-auth/master/install.sh | bash

The wizard backs up your existing ~/.config/opencode/opencode.json, merges in the plugin entry + a curated 7-model provider.windsurf block (additive, your other settings are untouched), then launches opencode auth login --provider windsurf so you can sign in.

Flags:

| Flag | Effect | |---|---| | --no-login | Skip the sign-in step (run opencode auth login --provider windsurf later) | | --force | Overwrite an existing provider.windsurf block (default: keep what's there) | | --help | Show usage and exit |

Pass them through the pipe:

curl -fsSL https://raw.githubusercontent.com/rsvedant/opencode-windsurf-auth/master/install.sh | bash -s -- --no-login

Option B - manual

Paste this into ~/.config/opencode/opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": ["opencode-windsurf-auth@beta"],
  "provider": {
    "windsurf": {
      "name": "Cognition (Windsurf)",
      "npm": "@ai-sdk/openai-compatible",
      "options": { "baseURL": "http://127.0.0.1:42100/v1" },
      "models": {
        "claude-opus-4.7": {
          "name": "Claude Opus 4.7",
          "limit": { "context": 1000000, "output": 128000 },
          "attachment": true,
          "modalities": { "input": ["text", "image"], "output": ["text"] },
          "variants": {
            "low": {}, "medium": {}, "high": {}, "xhigh": {}, "max": {},
            "low-fast": {}, "medium-fast": {}, "high-fast": {}, "xhigh-fast": {}, "max-fast": {}
          }
        },
        "gpt-5.5": {
          "name": "GPT 5.5",
          "limit": { "context": 1050000, "output": 128000 },
          "attachment": true,
          "modalities": { "input": ["text", "image"], "output": ["text"] },
          "variants": {
            "none": {}, "low": {}, "medium": {}, "high": {}, "xhigh": {},
            "none-priority": {}, "low-priority": {}, "medium-priority": {}, "high-priority": {}, "xhigh-priority": {}
          }
        },
        "kimi-k2.6": {
          "name": "Kimi K2.6",
          "limit": { "context": 262144, "output": 262144 },
          "attachment": true,
          "modalities": { "input": ["text", "image"], "output": ["text"] }
        },
        "gemini-3.5-flash": {
          "name": "Gemini 3.5 Flash",
          "limit": { "context": 1048576, "output": 65536 },
          "attachment": true,
          "modalities": { "input": ["text", "image"], "output": ["text"] },
          "variants": { "minimal": {}, "low": {}, "medium": {}, "high": {} }
        },
        "claude-opus-4.6": {
          "name": "Claude Opus 4.6",
          "limit": { "context": 1000000, "output": 128000 },
          "attachment": true,
          "modalities": { "input": ["text", "image"], "output": ["text"] },
          "variants": { "thinking": {}, "1m": {}, "thinking-1m": {}, "fast": {}, "thinking-fast": {} }
        },
        "swe-1.6": {
          "name": "SWE 1.6",
          "limit": { "context": 1000000, "output": 128000 },
          "attachment": true,
          "modalities": { "input": ["text", "image"], "output": ["text"] },
          "variants": { "fast": {}, "fast-low": {}, "fast-medium": {}, "fast-high": {} }
        },
        "deepseek-v4": {
          "name": "DeepSeek V4",
          "limit": { "context": 1000000, "output": 384000 }
        }
      }
    }
  }
}

Sign in:

opencode auth login --provider windsurf
# → browser opens; sign in with your Windsurf account
# → credential is saved automatically

Want the full catalog (94 models, all variants)? Copy opencode_config_example.json verbatim.

Use

opencode run --model=windsurf/swe-1.6 "hi"
opencode run --model=windsurf/claude-opus-4.7:high "what does this codebase do?"
opencode run --model=windsurf/kimi-k2.6 -f screenshot.png -- "describe this image"

Variants pass through as model suffixes (:low, :high, :thinking, etc.) — same syntax Windsurf's own clients use.

Image attachments

Models with "attachment": true in your config accept image content parts via opencode's -f <path> flag (and the TUI's paste/drag-drop). The 7-model curated set above marks six as image-capable (everything except deepseek-v4). The full 94-model catalog in opencode_config_example.json flags 55 models as image-capable based on per-model verification against models.dev. Append custom models without the attachment flag and opencode automatically blocks image attachment in the UI.

Sign in / sign out

opencode auth login --provider windsurf   # browser-based, recommended
opencode auth logout windsurf             # clears the credential

# Headless / SSH / no-browser fallback:
npx opencode-windsurf-auth login --manual
npx opencode-windsurf-auth whoami         # show signed-in account
npx opencode-windsurf-auth status         # show credentials path + version

Credentials are stored mode 0600 at the XDG-config location opencode itself uses, on every platform:

  • Linux + macOS + Windows: ~/.config/opencode-windsurf-auth/credentials.json

(opencode doesn't honor %APPDATA% on Windows either, it follows XDG conventions everywhere — so the plugin's credentials sit next to opencode's own config.)

How it works

opencode loads the plugin from npm via its own cache. The plugin binds a Bearer-gated local proxy at 127.0.0.1:42100, translates OpenAI-shaped chat requests into Cognition's Connect-RPC GetChatMessage wire format, and streams the response back as OpenAI SSE. Tool calls, MCP servers, reasoning deltas, token usage, image attachments — all wired through. No language_server runs. Auth uses a loopback OAuth callback on a random ephemeral port; the long-lived api_key from RegisterUser is then exchanged for a short-lived user_jwt on every chat. For the wire-protocol details see docs/CASCADE_PROTOCOL.md.

Troubleshooting

Another process holds 127.0.0.1:42100. Find and stop it:

lsof -nP -iTCP:42100 -sTCP:LISTEN
kill -9 <PID>

The plugin refuses to silently adopt a foreign listener on that port because a squatter could otherwise capture your prompts. Re-run opencode auth login after killing the squatter.

The CLI fallback prints a URL you can click manually:

npx opencode-windsurf-auth login --manual

Or paste the URL it shows into any browser on a machine that can reach your headless host (the loopback callback won't work cross-host, so use --manual for fully-headless setups).

Only models with "attachment": true in your opencode.json will receive image content from opencode. If you added a custom model and want image attachments, add:

"attachment": true,
"modalities": { "input": ["text", "image"], "output": ["text"] }

(Adding the flag to a model that doesn't actually support vision will still let opencode attach the image, but the model will respond with "I can't read images" — that's the model talking, not the plugin.)

Confirm the plugin entry is present:

jq '.plugin' ~/.config/opencode/opencode.json
# Should contain "opencode-windsurf-auth@beta"

Then nuke opencode's plugin cache so it re-resolves from npm:

rm -rf ~/.cache/opencode/packages/opencode-windsurf-auth@beta
opencode auth login

Project layout

src/
├── plugin.ts                # Proxy server + opencode hooks (auth + chat.params)
├── cli.ts                   # `opencode-windsurf-auth` standalone CLI
├── cloud-direct/            # Cognition Connect-RPC wire client
│   ├── chat.ts              # GetChatMessage stream + SSE adapter
│   ├── wire.ts              # Proto + Connect framing
│   ├── auth.ts              # GetUserJwt mint + cache
│   └── metadata.ts          # Metadata proto builder
├── oauth/                   # OAuth flow + credentials.json
│   ├── login.ts             # Loopback + manual-paste sign-in
│   ├── register-user.ts     # POST register.windsurf.com → api_key
│   └── storage.ts           # O_EXCL-locked, mode-0600 atomic write
└── plugin/
    ├── credentials-resolver.ts
    └── models.ts            # 110+ canonical model IDs + variant resolver

Development

git clone https://github.com/rsvedant/opencode-windsurf-auth.git
cd opencode-windsurf-auth
bun install
bun run typecheck
bun run build
bun test

Further reading

  • docs/CASCADE_PROTOCOL.md — Windsurf 2.x wire-format notes (why RawGetChatMessage is dead, why model UIDs are now strings, required metadata fields, etc.)

License

MIT