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-see-image

v1.3.2

Published

Give non-vision opencode models the ability to see images/screenshots by routing them to a vision-capable model (MiniMax M3 via opencode-go by default).

Downloads

2,316

Readme

opencode-see-image

give non-vision opencode models the ability to see images and screenshots by routing them to a vision-capable model.

when a user attaches a screenshot to a text-only model, opencode rejects it with an error. This plugin intercepts that flow by registering a see_image tool that sends the image to a vision model and returns a textual description the primary model can reason about.

when the active model is already vision-capable (its capabilities.input.image is true), the plugin stays out of the way: the see_image instructions are not injected, and a stray see_image call returns a harmless "you already saw this natively" note instead of an error. beware that this might lead to issues while switching models mid session, so a clean session might fix most of your problems (if any).

install

one command (recommended):

opencode plugin opencode-see-image --global

This installs the package and adds it to your config. Then restart opencode.

edit config manually:

Add the plugin to your opencode config:

// ~/.config/opencode/opencode.jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "plugin": ["opencode-see-image"]
}

Then restart opencode.

install via your agent (for some reason?)

ask your agent:

install the opencode-see-image plugin

it'll run opencode plugin opencode-see-image --global and tell you to restart.

prerequisites

you need a connected vision-capable provider. The plugin auto-detects whichever you have connected, either of these work:

free (OpenCode Zen)

  1. run /connect in opencode
  2. select opencode (OpenCode Zen)
  3. paste your API key from opencode.ai/auth

the plugin uses mimo-v2.5-free automatically — if you don't have an OpenCode Go sub, it skips the paid model entirely (no errors) and routes to the free model.

paid, w/ OpenCode Go

  1. run /connect in opencode
  2. select opencode-go
  3. paste your API key from opencode.ai/auth

the plugin prefers minimax-m3 via opencode-go when available.

paid, w/ another provider

set the SEE_IMAGE_* env vars to point at any Anthropic-Messages-compatible endpoint. see Configuration below.

the resolve order: explicit SEE_IMAGE_API_KEY env → configured SEE_IMAGE_PROVIDERopencode-go (MiniMax M3) if you have a Go sub connectedopencode (mimo-v2.5-free). If no Go sub is connected, opencode-go is skipped so free users never hit a "model not found" error.

how the eye surgery works

user attaches screenshot
        |
        v
opencode rejects it: 'this model does not support image input'
        |      (the model only sees the filename, or nothing at all)
        v
plugin's system-prompt instructions tell the model to call see_image
        |
        v
see_image tool resolves the image:
  1. asks the opencode server for the session's attachments (exact name,
     then unicode-normalized name, then most recent image)
  2. falls back to reading opencode's SQLite DB directly (this session,
     then any session)
  3. falls back to a filesystem search
  4. if the name matched nothing but the session has an image, uses the
     most recent one anyway
        |
        v
sends the image to the vision model and returns the textual description
        |
        v
primary model answers using the description

if everything misses, the error message lists the images actually attached to the session so the model can retry with a correct filename.

security: the vision model gets no tools

the vision call handles attacker-influenceable content (the image itself, plus the question), so the helper model is locked out of the agent toolset on every route:

  • SDK route (default): the helper session is created with a wildcard deny ("*": false plus explicit per-tool denies), which opencode converts to session permission rules that strip every tool — bash, edit, webfetch, MCP tools, all of it — from the request before the vision model ever sees it.
  • CLI fallback (free Zen models): the spawned opencode run gets a deny-all OPENCODE_PERMISSION config and runs without --dangerously-skip-permissions, so no tool is offered and nothing can be auto-approved.
  • HTTP route (apiKey set): a plain Anthropic-Messages API call with no tools field at all.

versions before 1.3.1 passed tools: {} on the SDK route, which opencode treats as "no overrides" — the vision model received the full toolset and could actually execute commands (#6). update if you're on an older version.

the see_image tool

the plugin registers a see_image tool with two arguments:

| arg | type | required? | description | |---|---|---|---| | filePath | string | n | path to the image. Absolute path, or a bare filename like "Screenshot 2026-06-18 at 17.32.24.png" to auto-locate. Omit (or pass "latest") to use the most recent image attached to the conversation. | | question | string | n | a specific question about the image. Defaults to a general detailed description. Use this to focus on a particular detail (e.g. "What error is shown in the terminal?"). |

your model calls this tool automatically when you attach a screenshot, you don't need to do anything special. The question arg is optional; the model uses it when you ask something specific about the image.

configuration

you can configure the vision route two ways: via plugin options in your opencode config (recommended), or via SEE_IMAGE_* env vars. The plugin uses opencode's SDK client by default (handles auth automatically). Set SEE_IMAGE_API_KEY to bypass the SDK and call an HTTP endpoint directly.

via plugin options (config)

Set the vision route in your opencode config (~/.config/opencode/opencode.json or opencode.json in a project) using the tuple form of the plugin array entry:

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": [
    [
      "opencode-see-image",
      {
        "provider": "egon-proxy",
        "model": "qwen3.6-35b-a3b:latest"
      }
    ]
  ]
}

Supported option keys (all optional):

| option | env var fallback | default | description | |---|---|---|---| | provider | SEE_IMAGE_PROVIDER | opencode-go | Provider ID for SDK routing | | model | SEE_IMAGE_MODEL | minimax-m3 | Vision model ID | | endpoint | SEE_IMAGE_ENDPOINT | https://opencode.ai/zen/go/v1/messages | HTTP endpoint (only used with apiKey) | | apiKey | SEE_IMAGE_API_KEY | (uses SDK) | Bypass SDK, call HTTP endpoint directly | | timeout | SEE_IMAGE_TIMEOUT | 30000 | Per-candidate timeout in ms. Prevents hanging on slow models. | | apiVersion | SEE_IMAGE_API_VERSION | 2023-06-01 | anthropic-version header (HTTP mode only) | | userAgent | SEE_IMAGE_USER_AGENT | (Chrome UA) | User-Agent header (HTTP mode only) |

precedence: per field, resolution is plugin option → SEE_IMAGE_* env var → built-in default. Config options take precedence over env vars; env vars remain the fallback when an option is unset. Existing env-var-only setups are unchanged.

note on secrets: a project-level opencode.json usually ends up in git — keep apiKey out of it and use the SEE_IMAGE_API_KEY env var instead.

via env vars

same settings as environment variables:

| env var | default | description | |---|---|---| | SEE_IMAGE_MODEL | minimax-m3 | Vision model ID | | SEE_IMAGE_PROVIDER | opencode-go | Provider ID for SDK routing | | SEE_IMAGE_API_KEY | (uses SDK) | Bypass SDK, call HTTP endpoint directly | | SEE_IMAGE_ENDPOINT | https://opencode.ai/zen/go/v1/messages | HTTP endpoint (only used if SEE_IMAGE_API_KEY is set) | | SEE_IMAGE_API_VERSION | 2023-06-01 | anthropic-version header (HTTP mode only) | | SEE_IMAGE_USER_AGENT | (Chrome UA) | User-Agent header (HTTP mode only) | | SEE_IMAGE_TIMEOUT | 30000 | Per-candidate timeout in ms. Prevents hanging on slow models. |

using a different vision model

any Anthropic-Messages-compatible endpoint works. for example, to use a direct MiniMax key:

export SEE_IMAGE_ENDPOINT="https://api.minimax.io/v1/messages"
export SEE_IMAGE_MODEL="minimax-m3"
export SEE_IMAGE_API_KEY="your-minimax-key"

to use a different opencode-go model (e.g. Kimi K2.7):

export SEE_IMAGE_MODEL="kimi-k2.7-code"

verified vision-capable models

Free (OpenCode Zen):

| model | Notes | |---|---| | mimo-v2.5-free | free. may be a bit slow. default fallback when only Zen is connected (routed via CLI). | | big-pickle | for some reason, big pickle works as an image capable model when called through the sdk w/ an active opencode go sub. |

paid (OpenCode Go):

| model | speed | notes | |---|---|---| | minimax-m3 | ~3000ms | default. fast, clean, and accurate. | | kimi-k2.7-code | ~7000ms | clean and accurate. | | kimi-k2.6 | ~12000ms | accurate but slow. | | qwen3.7-plus | ~15000ms | slow, spends a bit more tokens because of thinking. |

updating

auto-update (built in): uses the opencode-plugin-update-kit and shows a toast: "opencode-see-image updated to X.Y.Z, restart opencode to apply". You just need to restart opencode to load the new version.

manual update:

opencode plugin opencode-see-image --force --global

then restart opencode.

pin a version in your config to opt out of auto-updates:

"plugin": ["[email protected]"]

platform support

works on macOS, Windows, and Linux, in both the CLI/TUI (Bun runtime) and the desktop app (whose server runs on Node inside Electron). The package ships compiled JS and avoids Bun-only APIs at load time, so it loads on either runtime. Attachment lookup goes through the opencode server API first (works everywhere, including remote workspaces), with a direct SQLite read and a filesystem search as fallbacks.

file search locations

when opencode rejects an image attachment, the model only receives a bare filename. see_image first checks the opencode DB (cross-platform), then falls back to searching these filesystem locations, in order:

macOS

  1. $TMPDIR/TemporaryItems/NSIRD_screencaptureui_*/ (where macOS stashes dragged screenshots)
  2. $TMPDIR/TemporaryItems/
  3. ~/Desktop, ~/Downloads, current working directory

Windows

  1. %TEMP% / %TMP% (dragged/temp images)
  2. %USERPROFILE%\Pictures\Screenshots and the OneDrive-redirected %USERPROFILE%\OneDrive\Pictures\Screenshots (Win+PrtScn / Snipping Tool)
  3. %USERPROFILE%\Pictures
  4. ~\Desktop, ~\Downloads, current working directory

Linux

  1. $TMPDIR / /tmp
  2. ~/Pictures/Screenshots, ~/Pictures
  3. ~/Desktop, ~/Downloads, current working directory

pass an absolute filePath to skip the search.

License

MIT