Before changing a documented subsystem, read its design reference and verify the linked source. When preparing or reviewing a PR, follow the same page's documentation update, semantic change description, and review rules.
Write and review changes against the code standards.
Before reviewing a community PR, read contributors: what stops a review for possible harm, what is closed unreviewed, and the authors whose PRs are closed on sight.
Before changing code, read LESSONS.md: what recent merged work got wrong and the rule that would have caught it.
Some built-in subscriptions are deprecated. Reaching them can break their vendors' terms, so they are moving out of magpie into community OpenCode plugins, which keeps magpie itself from being banned. Each one has a plugin that does the same job:
| Subscription | id | Plugin (npm) | Mover |
|---|---|---|---|
| Command Code | commandcode-plan |
@magpie-community/opencode-commandcode-auth |
internal/provider/migrate_side.go |
| Cursor | cursor |
@magpie-community/opencode-cursor-auth |
internal/provider/migrate_side.go |
| Devin | devin |
@magpie-community/opencode-devin-auth |
internal/provider/migrate_side.go |
| Factory | factory |
@magpie-community/opencode-factory-auth |
internal/provider/migrate_factory.go |
| Grok | grok |
@magpie-community/opencode-grok-auth |
internal/provider/migrate_side.go |
| Kiro | kiro |
@magpie-community/opencode-kiro-auth |
internal/provider/migrate_kiro.go |
| Xiaomi MiMo | mimo-app |
@magpie-community/opencode-mimo-auth |
internal/provider/migrate_mimo.go |
| Qoder, Qoder CN | qoder, qoder-cn |
@magpie-community/opencode-qoder-auth |
internal/provider/migrate_qoder.go |
| WorkBuddy, WorkBuddy AI | workbuddy, workbuddy-ai |
@magpie-community/opencode-workbuddy-auth |
internal/provider/migrate_workbuddy.go |
| ZCode | zcode |
@magpie-community/opencode-zcode-auth |
internal/provider/migrate_zcode.go |
| Zed | zed |
@magpie-community/opencode-zed-auth |
internal/provider/migrate_zed.go |
The movers map in internal/provider/migrate*.go is the source of truth.
TestMovedBuiltinsSayTheirPlugin fails when a mover has no notice in its
code.
Two cases decide it:
- Moved: the user moved the subscription onto its plugin, from the
editor's "Move to plugin" (or
provider.Adopt). Itsmigrations.jsonstate isplugin(provider.Moved(id)). A new user never sees a deprecated built-in: the Add sheet leaves one with no account out (unusedSubin app.js), so it is installed from the Plugins page. A user who installs the plugin themselves is moved too (provider.HandOver): at once when the built-in has no accounts, from the gateway's hourly loop (KeepRetiringMoved) when it has, unless they moved back or the plugin is signed in under its own-pluginid already. Until then the Add sheet shows the plugin's tile only (replacedSubin app.js). - Not moved: the user is still signed in through the built-in.
For a moved subscription, the plugin does everything: sign-in, refresh,
models, requests, usage and errors. It runs in the plugin host
(internal/plugin). The built-in's code in internal/provider/<name>*.go,
internal/gateway/<name>.go, internal/zed and internal/qoder doesn't run
for it at all. The gateway sends its requests to the plugin's fetch, not to
the built-in's translator.
So a bug report about one of these subscriptions is usually about the plugin:
- Check whether the user's subscription is moved. A moved provider's row in
/api/providershasmove.state == "plugin"; the provider id is inonPlugins. - Fix the plugin in the community repo,
magpie-community/plugins
(
packages/<name>, provider id = the built-in's id; checked out locally at~/workspace/projects/magpie-commuity-plugins). Publish a new version. - Raise the mover's
minto that version.keepMovedCurrentthen updates every moved user's plugin. - Make the same fix in the built-in only if it should also reach users who haven't moved. A fix made only in the built-in does nothing for moved users.
This magpie-side code still runs for moved subscriptions:
- the plugin host:
internal/plugin,host.js; internal/provider/plugins.go,plugin_usage.go(movedCards) andpluginsignin.go;- the move itself:
internal/provider/migrate*.go; - the GUI's plugin paths in
internal/gui/assets/app.js:subOf,pluginSubsandstartPluginSignIn.
A test against the built-in alone doesn't prove anything for moved users. To
compare the two, use the parity tests: internal/gateway/plugin_*_test.go.