feat: surface plugin auth providers in the login picker by anoldguy · Pull Request #13921 · anomalyco/opencode

What does this PR do?

Fixes #13917.

Plugins can register auth for providers not in models.dev, but those providers don't show up in the opencode auth login picker. The workaround is passing the provider ID as a positional arg — which works fine if you set up the environment yourself, but falls apart in teams or managed setups where users shouldn't need to know what provider ID their plugin registered. The picker is supposed to be the discovery mechanism; if it doesn't show what's available, it's not doing its job.

This adds a resolvePluginProviders function that collects auth providers from loaded plugins, deduplicates, and appends them to the picker with a (plugin) hint. Providers already in models.dev are not added again — they're already in the picker, and the existing post-selection logic already checks Plugin.list() for plugin auth on any selected provider, so plugins like codex and copilot that register auth for built-in providers continue to work as before. This change only adds picker entries for providers that would otherwise be invisible.

The existing enabled_providers / disabled_providers config is respected for plugin providers too — same filtering logic, same precedence.

How did you verify your code works?

resolvePluginProviders is a pure function, so the unit tests exercise it directly without mocking — feed it different combinations of hooks, existing providers, and enabled/disabled sets, check what comes out.

For the end-to-end path, I pointed OPENCODE_MODELS_API_URL at a localhost server with a custom provider definition and ran bun dev -- auth login with a plugin registering auth.provider: "portkey-test". It shows up in the picker with a (plugin) hint, is searchable, and selectable.

# Manual Test Run
» bun dev -- auth login
$ bun run --cwd packages/opencode --conditions=browser src/index.ts auth login

┌  Add credential
│
◆  Select provider

│  Search: port (1 match)
│  ● portkey-test (plugin)
│  ↑/↓ to select  Enter: confirm • Type: to search
└