qoder: Qoder CN is moved onto its plugin too, @magpie-community/opencode-qoder-auth 0.2.0, which serves it as "qoder-cn" (the user: 为啥 Qoder CN 没有插件啊) — the plugin had Qoder alone when the move was made (09-30), Qoder CN coming to magpie a day later, so Qoder CN stayed a built-in that wasn't deprecated. 0.2.0 serves both sites (Qoder CN signing in on qoder.cn with its own client id and no redirect_uri, chatting on gateway.qoder.com.cn, and on its device token when qoder.cn refuses the job token), so movers now has "qoder-cn" beside "qoder", both from qoderMover(id): an account's pairs, machine id and, for one chatting on its device token, deviceChat go to the plugin and come back. Both movers' min is 0.2.0. The PLUGIN-SERVED notices in internal/qoder, internal/provider/qoder*.go and internal/gateway/qoder.go and AGENTS.md's table now name both ids rather than saying Qoder CN isn't moved. TestQoderCNMover (a device-chat account and a job-token one, round trip) fails with deviceChat not brought back. go vet, go build -tags nogui (darwin, GOOS=linux), GOOS=windows go build, go test -tags nogui -count=1 ./... under a temp HOME pass.

This commit is contained in:
yetone committed 2026-10-02 19:59:36 +08:00
1 parent 9845e3af51
commit f099d07e92
15 files changed
+125 -105

No files matched your search

+1 -1
View File
@@ -16,7 +16,7 @@ that does the same job:
| 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.com only; Qoder CN isn't moved) | `qoder` | `@magpie-community/opencode-qoder-auth` | `internal/provider/migrate_qoder.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` |
+7 -8
View File
@@ -1,14 +1,13 @@
package gateway
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") is a deprecated built-in
// subscription served by its plugin, @magpie-community/opencode-qoder-auth,
// once moved onto it (provider.Moved; the default for a new sign-in). A
// moved one's sign-ins, models, requests and usage are all the plugin's,
// never this code's (only the move, in migrate*.go, still reads its
// accounts). A fix here alone doesn't reach those users; fix the plugin
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") and Qoder CN ("qoder-cn")
// are deprecated built-in subscriptions served by their plugin,
// @magpie-community/opencode-qoder-auth, each once moved onto it
// (provider.Moved; the default for a new sign-in). A moved one's
// sign-ins, models, requests and usage are all the plugin's, never this
// code's (only the move, in migrate*.go, still reads its accounts). A fix here alone doesn't reach those users; fix the plugin
// (github.com/magpie-community/plugins, packages/qoder) and raise the
// mover's min in internal/provider/migrate_qoder.go. Qoder CN ("qoder-cn")
// isn't moved and still runs here.
// movers' min in internal/provider/migrate_qoder.go.
import (
"bufio"
+17
View File
@@ -97,6 +97,23 @@ func TestQoderMover(t *testing.T) {
})
}
// A Qoder CN account keeps its site, and one that chats on its device
// token keeps doing so.
func TestQoderCNMover(t *testing.T) {
c1 := qoder.Credential{Site: QoderCNID, UID: "u1", Email: "a@q.cn", Token: "d1", RefreshToken: "dr1", DeviceToken: "d1", DeviceRefresh: "dr1", DeviceChat: true, ExpiresAt: 1_900_000_000_123, MachineID: "m1"}
c2 := qoder.Credential{Site: QoderCNID, UID: "u2", Token: "t2", RefreshToken: "r2", DeviceToken: "d2", ExpiresAt: 1_900_000_000_456, MachineID: "m2"}
roundTrip(t, QoderCNID, []savedLogin{
{Agent: QoderCNID, User: "a@q.cn", First: true, On: true, Auth: authOf(t, c1)},
{Agent: QoderCNID, User: "u2", Auth: authOf(t, c2)},
}, func(t *testing.T, a, b savedLogin) {
ca, _ := qoderSaved(a)
cb, _ := qoderSaved(b)
if !reflect.DeepEqual(ca, cb) {
t.Fatalf("qoder-cn %s: %+v, want %+v", a.User, cb, ca)
}
})
}
func TestFactoryMover(t *testing.T) {
c1 := factoryCreds{Access: "a1", Refresh: "r1", ExpiresAt: 1_900_000_000_000, Org: "org_1", Active: "fo1", Email: "a@f.com", UserID: "user_1", Region: "eu", Prem: "llm.example.com"}
c2 := factoryCreds{Access: "a2", Refresh: "r2", ExpiresAt: 1_900_000_000_001, UserID: "user_2"}
+23 -8
View File
@@ -4,20 +4,31 @@ import (
"encoding/json"
"errors"
"time"
"github.com/yetone/magpie/internal/qoder"
)
// Qoder's accounts on @magpie-community/opencode-qoder-auth, as its device
// Qoder's and Qoder CN's accounts on @magpie-community/opencode-qoder-auth,
// which serves both sites as providers "qoder" and "qoder-cn", as its device
// sign-in keeps one: the job token pair as access and refresh (the refresh
// token is spent on use, so it moves rather than being copied), the device
// token pair and machine id beside them.
// token pair and machine id beside them. A Qoder CN account that chats on
// its device token (DeviceChat) says so, its device pair as access and
// refresh.
func init() {
movers["qoder"] = &mover{
for _, id := range []string{"qoder", QoderCNID} {
movers[id] = qoderMover(id)
}
}
func qoderMover(id string) *mover {
return &mover{
pkg: "@magpie-community/opencode-qoder-auth",
min: "0.1.4", // a failure's status and its sign-in mark as the built-in's; a refused refresh marks the sign-in
agents: []string{"qoder"},
min: "0.2.0", // Qoder CN as "qoder-cn", its device-token chat as the built-in's
agents: []string{id},
out: func() ([]Moving, error) {
// no refresh of the built-in's runs while the pairs are read
ls := qoderLogins()
ls := qoderLoginsOf(id)
qoderMu.Lock()
defer qoderMu.Unlock()
var out []Moving
@@ -39,18 +50,21 @@ func init() {
"deviceToken": c.DeviceToken,
"deviceRefresh": c.DeviceRefresh,
}})
if c.DeviceChat {
out[len(out)-1].Auth["deviceChat"] = true
}
}
return out, nil
},
back: func(ls []savedLogin, user string, auth map[string]any) ([]savedLogin, string, error) {
access, uid := str(auth["access"]), str(auth["uid"])
if access == "" || uid == "" {
return ls, "", errors.New("Qoder: an unreadable plugin sign-in")
return ls, "", errors.New(qoder.SiteOf(id).Name + ": an unreadable plugin sign-in")
}
if user == "" {
user = firstNonEmpty(str(auth["accountId"]), str(auth["email"]), uid)
}
i := backInto(&ls, "qoder", user)
i := backInto(&ls, id, user)
c, _ := qoderSaved(ls[i])
c.UID, c.Token, c.RefreshToken, c.ExpiresAt = uid, access, str(auth["refresh"]), num(auth["expires"])
c.Email = firstNonEmpty(str(auth["email"]), c.Email)
@@ -58,6 +72,7 @@ func init() {
c.MachineID = firstNonEmpty(str(auth["machineId"]), c.MachineID)
c.DeviceToken = firstNonEmpty(str(auth["deviceToken"]), c.DeviceToken)
c.DeviceRefresh = firstNonEmpty(str(auth["deviceRefresh"]), c.DeviceRefresh)
c.DeviceChat = auth["deviceChat"] == true
b, err := json.Marshal(c)
if err != nil {
return ls, "", err
+7 -8
View File
@@ -1,14 +1,13 @@
package provider
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") is a deprecated built-in
// subscription served by its plugin, @magpie-community/opencode-qoder-auth,
// once moved onto it (provider.Moved; the default for a new sign-in). A
// moved one's sign-ins, models, requests and usage are all the plugin's,
// never this code's (only the move, in migrate*.go, still reads its
// accounts). A fix here alone doesn't reach those users; fix the plugin
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") and Qoder CN ("qoder-cn")
// are deprecated built-in subscriptions served by their plugin,
// @magpie-community/opencode-qoder-auth, each once moved onto it
// (provider.Moved; the default for a new sign-in). A moved one's
// sign-ins, models, requests and usage are all the plugin's, never this
// code's (only the move, in migrate*.go, still reads its accounts). A fix here alone doesn't reach those users; fix the plugin
// (github.com/magpie-community/plugins, packages/qoder) and raise the
// mover's min in internal/provider/migrate_qoder.go. Qoder CN ("qoder-cn")
// isn't moved and still runs here.
// movers' min in internal/provider/migrate_qoder.go.
import (
"context"
+7 -8
View File
@@ -1,14 +1,13 @@
package provider
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") is a deprecated built-in
// subscription served by its plugin, @magpie-community/opencode-qoder-auth,
// once moved onto it (provider.Moved; the default for a new sign-in). A
// moved one's sign-ins, models, requests and usage are all the plugin's,
// never this code's (only the move, in migrate*.go, still reads its
// accounts). A fix here alone doesn't reach those users; fix the plugin
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") and Qoder CN ("qoder-cn")
// are deprecated built-in subscriptions served by their plugin,
// @magpie-community/opencode-qoder-auth, each once moved onto it
// (provider.Moved; the default for a new sign-in). A moved one's
// sign-ins, models, requests and usage are all the plugin's, never this
// code's (only the move, in migrate*.go, still reads its accounts). A fix here alone doesn't reach those users; fix the plugin
// (github.com/magpie-community/plugins, packages/qoder) and raise the
// mover's min in internal/provider/migrate_qoder.go. Qoder CN ("qoder-cn")
// isn't moved and still runs here.
// movers' min in internal/provider/migrate_qoder.go.
import (
"context"
+7 -8
View File
@@ -1,14 +1,13 @@
package qoder
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") is a deprecated built-in
// subscription served by its plugin, @magpie-community/opencode-qoder-auth,
// once moved onto it (provider.Moved; the default for a new sign-in). A
// moved one's sign-ins, models, requests and usage are all the plugin's,
// never this code's (only the move, in migrate*.go, still reads its
// accounts). A fix here alone doesn't reach those users; fix the plugin
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") and Qoder CN ("qoder-cn")
// are deprecated built-in subscriptions served by their plugin,
// @magpie-community/opencode-qoder-auth, each once moved onto it
// (provider.Moved; the default for a new sign-in). A moved one's
// sign-ins, models, requests and usage are all the plugin's, never this
// code's (only the move, in migrate*.go, still reads its accounts). A fix here alone doesn't reach those users; fix the plugin
// (github.com/magpie-community/plugins, packages/qoder) and raise the
// mover's min in internal/provider/migrate_qoder.go. Qoder CN ("qoder-cn")
// isn't moved and still runs here.
// movers' min in internal/provider/migrate_qoder.go.
import "strings"
+7 -8
View File
@@ -1,14 +1,13 @@
package qoder
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") is a deprecated built-in
// subscription served by its plugin, @magpie-community/opencode-qoder-auth,
// once moved onto it (provider.Moved; the default for a new sign-in). A
// moved one's sign-ins, models, requests and usage are all the plugin's,
// never this code's (only the move, in migrate*.go, still reads its
// accounts). A fix here alone doesn't reach those users; fix the plugin
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") and Qoder CN ("qoder-cn")
// are deprecated built-in subscriptions served by their plugin,
// @magpie-community/opencode-qoder-auth, each once moved onto it
// (provider.Moved; the default for a new sign-in). A moved one's
// sign-ins, models, requests and usage are all the plugin's, never this
// code's (only the move, in migrate*.go, still reads its accounts). A fix here alone doesn't reach those users; fix the plugin
// (github.com/magpie-community/plugins, packages/qoder) and raise the
// mover's min in internal/provider/migrate_qoder.go. Qoder CN ("qoder-cn")
// isn't moved and still runs here.
// movers' min in internal/provider/migrate_qoder.go.
import (
"crypto/aes"
+7 -8
View File
@@ -13,15 +13,14 @@
// phone number and exist only there. A Site holds each one's hosts.
package qoder
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") is a deprecated built-in
// subscription served by its plugin, @magpie-community/opencode-qoder-auth,
// once moved onto it (provider.Moved; the default for a new sign-in). A
// moved one's sign-ins, models, requests and usage are all the plugin's,
// never this code's (only the move, in migrate*.go, still reads its
// accounts). A fix here alone doesn't reach those users; fix the plugin
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") and Qoder CN ("qoder-cn")
// are deprecated built-in subscriptions served by their plugin,
// @magpie-community/opencode-qoder-auth, each once moved onto it
// (provider.Moved; the default for a new sign-in). A moved one's
// sign-ins, models, requests and usage are all the plugin's, never this
// code's (only the move, in migrate*.go, still reads its accounts). A fix here alone doesn't reach those users; fix the plugin
// (github.com/magpie-community/plugins, packages/qoder) and raise the
// mover's min in internal/provider/migrate_qoder.go. Qoder CN ("qoder-cn")
// isn't moved and still runs here.
// movers' min in internal/provider/migrate_qoder.go.
// OAuth device-flow configuration (verified against live captures).
const (
+7 -8
View File
@@ -1,14 +1,13 @@
package qoder
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") is a deprecated built-in
// subscription served by its plugin, @magpie-community/opencode-qoder-auth,
// once moved onto it (provider.Moved; the default for a new sign-in). A
// moved one's sign-ins, models, requests and usage are all the plugin's,
// never this code's (only the move, in migrate*.go, still reads its
// accounts). A fix here alone doesn't reach those users; fix the plugin
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") and Qoder CN ("qoder-cn")
// are deprecated built-in subscriptions served by their plugin,
// @magpie-community/opencode-qoder-auth, each once moved onto it
// (provider.Moved; the default for a new sign-in). A moved one's
// sign-ins, models, requests and usage are all the plugin's, never this
// code's (only the move, in migrate*.go, still reads its accounts). A fix here alone doesn't reach those users; fix the plugin
// (github.com/magpie-community/plugins, packages/qoder) and raise the
// mover's min in internal/provider/migrate_qoder.go. Qoder CN ("qoder-cn")
// isn't moved and still runs here.
// movers' min in internal/provider/migrate_qoder.go.
import (
"crypto/rand"
+7 -8
View File
@@ -1,14 +1,13 @@
package qoder
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") is a deprecated built-in
// subscription served by its plugin, @magpie-community/opencode-qoder-auth,
// once moved onto it (provider.Moved; the default for a new sign-in). A
// moved one's sign-ins, models, requests and usage are all the plugin's,
// never this code's (only the move, in migrate*.go, still reads its
// accounts). A fix here alone doesn't reach those users; fix the plugin
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") and Qoder CN ("qoder-cn")
// are deprecated built-in subscriptions served by their plugin,
// @magpie-community/opencode-qoder-auth, each once moved onto it
// (provider.Moved; the default for a new sign-in). A moved one's
// sign-ins, models, requests and usage are all the plugin's, never this
// code's (only the move, in migrate*.go, still reads its accounts). A fix here alone doesn't reach those users; fix the plugin
// (github.com/magpie-community/plugins, packages/qoder) and raise the
// mover's min in internal/provider/migrate_qoder.go. Qoder CN ("qoder-cn")
// isn't moved and still runs here.
// movers' min in internal/provider/migrate_qoder.go.
import (
"context"
+7 -8
View File
@@ -1,14 +1,13 @@
package qoder
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") is a deprecated built-in
// subscription served by its plugin, @magpie-community/opencode-qoder-auth,
// once moved onto it (provider.Moved; the default for a new sign-in). A
// moved one's sign-ins, models, requests and usage are all the plugin's,
// never this code's (only the move, in migrate*.go, still reads its
// accounts). A fix here alone doesn't reach those users; fix the plugin
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") and Qoder CN ("qoder-cn")
// are deprecated built-in subscriptions served by their plugin,
// @magpie-community/opencode-qoder-auth, each once moved onto it
// (provider.Moved; the default for a new sign-in). A moved one's
// sign-ins, models, requests and usage are all the plugin's, never this
// code's (only the move, in migrate*.go, still reads its accounts). A fix here alone doesn't reach those users; fix the plugin
// (github.com/magpie-community/plugins, packages/qoder) and raise the
// mover's min in internal/provider/migrate_qoder.go. Qoder CN ("qoder-cn")
// isn't moved and still runs here.
// movers' min in internal/provider/migrate_qoder.go.
import (
"bytes"
+7 -8
View File
@@ -1,14 +1,13 @@
package qoder
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") is a deprecated built-in
// subscription served by its plugin, @magpie-community/opencode-qoder-auth,
// once moved onto it (provider.Moved; the default for a new sign-in). A
// moved one's sign-ins, models, requests and usage are all the plugin's,
// never this code's (only the move, in migrate*.go, still reads its
// accounts). A fix here alone doesn't reach those users; fix the plugin
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") and Qoder CN ("qoder-cn")
// are deprecated built-in subscriptions served by their plugin,
// @magpie-community/opencode-qoder-auth, each once moved onto it
// (provider.Moved; the default for a new sign-in). A moved one's
// sign-ins, models, requests and usage are all the plugin's, never this
// code's (only the move, in migrate*.go, still reads its accounts). A fix here alone doesn't reach those users; fix the plugin
// (github.com/magpie-community/plugins, packages/qoder) and raise the
// mover's min in internal/provider/migrate_qoder.go. Qoder CN ("qoder-cn")
// isn't moved and still runs here.
// movers' min in internal/provider/migrate_qoder.go.
import (
"context"
+7 -8
View File
@@ -1,14 +1,13 @@
package qoder
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") is a deprecated built-in
// subscription served by its plugin, @magpie-community/opencode-qoder-auth,
// once moved onto it (provider.Moved; the default for a new sign-in). A
// moved one's sign-ins, models, requests and usage are all the plugin's,
// never this code's (only the move, in migrate*.go, still reads its
// accounts). A fix here alone doesn't reach those users; fix the plugin
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") and Qoder CN ("qoder-cn")
// are deprecated built-in subscriptions served by their plugin,
// @magpie-community/opencode-qoder-auth, each once moved onto it
// (provider.Moved; the default for a new sign-in). A moved one's
// sign-ins, models, requests and usage are all the plugin's, never this
// code's (only the move, in migrate*.go, still reads its accounts). A fix here alone doesn't reach those users; fix the plugin
// (github.com/magpie-community/plugins, packages/qoder) and raise the
// mover's min in internal/provider/migrate_qoder.go. Qoder CN ("qoder-cn")
// isn't moved and still runs here.
// movers' min in internal/provider/migrate_qoder.go.
import (
"context"
+7 -8
View File
@@ -1,14 +1,13 @@
package qoder
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") is a deprecated built-in
// subscription served by its plugin, @magpie-community/opencode-qoder-auth,
// once moved onto it (provider.Moved; the default for a new sign-in). A
// moved one's sign-ins, models, requests and usage are all the plugin's,
// never this code's (only the move, in migrate*.go, still reads its
// accounts). A fix here alone doesn't reach those users; fix the plugin
// PLUGIN-SERVED (see AGENTS.md): Qoder ("qoder") and Qoder CN ("qoder-cn")
// are deprecated built-in subscriptions served by their plugin,
// @magpie-community/opencode-qoder-auth, each once moved onto it
// (provider.Moved; the default for a new sign-in). A moved one's
// sign-ins, models, requests and usage are all the plugin's, never this
// code's (only the move, in migrate*.go, still reads its accounts). A fix here alone doesn't reach those users; fix the plugin
// (github.com/magpie-community/plugins, packages/qoder) and raise the
// mover's min in internal/provider/migrate_qoder.go. Qoder CN ("qoder-cn")
// isn't moved and still runs here.
// movers' min in internal/provider/migrate_qoder.go.
import (
"context"