magicrew-auth 0.3.40 → 0.3.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -75,8 +75,8 @@ curl -s "https://usemagpie.ai/api/latest?channel=stable" | grep -o '"version":"[
75
75
  | 22 | 同一账号有的请求 200、有的 403 `token无效`(`retryable=false`),换个时间又好了 | key 有两条签发路径时 store 与 magpie 各存一把,**静态挑一把必有一半踩空**。0.3.29 起 `keyCandidates()` 把 store 两槽 + `auth.access` 逐把打 chat,命中的写回 store;全被拒才交 402 让 magpie 换号。判据:`GET /v1/models` 对死 key **放行**,逐把探活必须用 `/v1/chat/completions` | CHANGELOG 0.3.29 · `tests/key-failover.mjs` |
76
76
  | 23 | 插件列表里别人有「已自动更新」徽章,magicrew 没有 | magpie 只自动更新包名以 `@magpie-community/` 开头的包(`internal/plugin/updates.go` 的 `Official()` 硬编码前缀);第三方 npm / git 源永远只提示。本插件用 `src/auto-maintenance.mjs` 复刻:读 `plugin-updates.json` 的 `waiting` → 调 `magpie plugin update` → 成功后补 `updated[]`(徽章读它)。判据:`plugin-updates.json` 的 waiting 有 `package:"Magicrew", git:true`;`findMagpieExe()` 能解析到 magpie 可执行文件。⚠ 更新后要重启 magpie 才加载新代码 | CHANGELOG 0.3.30 · `tests/auto-maintenance.mjs` |
77
77
  | 24 | 新装插件后没有任何签到记录,`plugin-checkin.json` 里没有 magicrew | magpie 的 `PluginCheckinOn()`:`pluginCheckins` 没有显式值时默认 **false**(只有 WorkBuddy / Trae / MiniMax / Qoder 有内置开关)。插件只能在加载时把 `settings.json` 的 `pluginCheckins[provider]` 补成 true —— **只在键不存在时补**,用户显式 false 不覆盖。判据:`settings.json` 的 `pluginCheckins` 有 `magicrew` / `magicrew-intl` 键 | CHANGELOG 0.3.30 · `src/auto-maintenance.mjs` |
78
- | 25 | 邀请上级选完,第二天签到后又变回别的号 | 0.3.40 起登录页「邀请上级」一个数字文本框:0=自动(首次用作者码,之后跟随最后登录 / 签到的滚动码)、1=当前首选账号(magpie 账号页 Make first 的 logins.json `first`);留空/非法文本回退 0。切首选后重新点 1 取新首选。选中即写 `magicrew-invite-policy-<site>.json`(fixed),`inviteToUse` 优先它;死号自动回落滚动→作者码。判据:`tests/invite-policy.mjs` | CHANGELOG 0.3.40 · `src/hooks/methods.mjs` |
79
- | 26 | 邀请上级的数字文本框有没有「右边实时显示账号」 | magpie 的 `prompts` 只有 `text` / `select`,没有复合控件;提示只有一行「自动=0;首选=1;不填=默认自动」;没有实时右侧显示,保存后回一条「新号挂在首选 X(码)」说明。要真正的右侧实时刷新得等上游加控件 | CHANGELOG 0.3.40 · `src/hooks/methods.mjs` |
78
+ | 25 | 邀请码选完,第二天签到后又变回别的号 | 0.3.41 起登录页「邀请码」一个数字文本框:灰色字显示当前模式;0=自动(首次用作者码,之后跟随最后登录 / 签到的滚动码)、1=当前首选账号(magpie 账号页 Make first 的 logins.json `first`);留空/非法文本回退 0。保存后直接接手机号验证码;切首选后重新点 1 取新首选。选中即写 `magicrew-invite-policy-<site>.json`(fixed),`inviteToUse` 优先它;死号自动回落滚动→作者码。判据:`tests/invite-policy.mjs` | CHANGELOG 0.3.40 · `src/hooks/methods.mjs` |
79
+ | 26 | 邀请码的数字文本框有没有「右边实时显示账号」 | magpie 的 `prompts` 只有 `text` / `select`,没有复合控件;灰色字(placeholder)每次点开按当前策略生成:自动 →「当前模式:自动,输入 1 切换:首选」;首选/固定 →「当前模式:…,输入 0 切换:自动」。没有实时右侧显示;保存后直接进手机号验证码,不再回「已保存」提示。要真正的右侧实时刷新得等上游加控件 | CHANGELOG 0.3.41 · `src/hooks/methods.mjs` |
80
80
  | 27 | 数字方法的账号列表是空的 / 顺序不对 | 首选来自 `~/.config/magpie/logins.json` 的 `first`(Make first 写入),账号的码来自 `magicrew-invite-codes-<site>.json`(签到/登录时 `rollInvite` 记录;老用户升级后 config 20s 由 `backfillInviteCodes()` 用 plugin-auth 的 JWT 补)。页面/`page/codes.js` 已在 0.3.36 删除 | CHANGELOG 0.3.40 · `src/store.mjs` |
81
81
 
82
82
  **坑 14 的两个附带判据**(都实测过):
package/CHANGELOG.md CHANGED
@@ -1,7 +1,21 @@
1
1
  # 更新记录
2
2
 
3
+ ## 0.3.41 — 2026-10-29
4
+
5
+ **按钮改名「邀请码」;灰色字显示当前模式;保存后直接接手机号验证码**
6
+
7
+ - 登录方式 `超级麦吉 邀请上级` → **`超级麦吉 邀请码`**(去掉歧义)
8
+ - 输入框灰色字(placeholder)每次点开按已保存策略实时生成:
9
+ - 自动 → `当前模式:自动,输入 1 切换:首选`
10
+ - 首选 / 固定 → `当前模式:首选`(或 `固定`)`,输入 0 切换:自动`
11
+ - 0 / 留空 / 非法文本 = 自动;1 = 当前首选账号;保存发生在手机验证码之前
12
+ - `authorize` 保存策略后**直接调用手机号验证码方法**:邀请码 → 手机号 → 验证码,
13
+ 不再返回「已保存」的失败提示
14
+ - `tests/invite-policy.mjs` 20 条(灰色字实时、ask 链、保存后接手机、首选切换)
15
+
3
16
  ## 0.3.40 — 2026-10-29
4
17
 
18
+
5
19
  **邀请上级简化:自动=0;首选=1(0.3.39 补丁)**
6
20
 
7
21
  按截图页面反馈,不再列 1..N 账号;只看 magpie 账号页「首选」:
package/README.md CHANGED
@@ -34,7 +34,7 @@
34
34
  - **默认开启自动签到** —— 安装后自动把本 provider 的插件签到设为开(`pluginCheckins` 缺省时补 true;你手动关掉的不会被改回)
35
35
  - **自动更新** —— 复用 magpie 的插件更新机制:发现自己的新版本后调 `magpie plugin update`,并在成功后写「已自动更新」记录;更新完要重启一次 magpie 才会加载新代码
36
36
  - **邀请码自动滚** —— 第一次注册带作者的码,之后每次登录都记住「上一个登录账号」的码,拿到新的就覆盖旧的
37
- - **邀请上级可固定** —— 登录页多一个按钮「邀请上级」:填数字,0=自动(首次用作者码,之后跟随最后登录 / 签到的滚动码),1=当前首选账号;留空 / 非法文本 = 0。切首选账号后再点一次 1 就换成新的首选
37
+ - **邀请码可设置** —— 登录页多一个按钮「邀请码」:一个数字框,灰色字显示当前模式;自动=0(首次作者码,之后跟随最后登录 / 签到的滚动码),首选=1(当前首选账号);留空 / 非法文本 = 0。保存后直接进手机号验证码;切首选账号后再点一次 1 就换成新的首选
38
38
 
39
39
  ---
40
40
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magicrew-auth",
3
- "version": "0.3.40",
3
+ "version": "0.3.41",
4
4
  "description": "超级麦吉 / MagiCrew for magpie and OpenCode — one package, two providers: letsmagic.cn (国内) and magicrew.ai (international). Password or web-JWT sign-in, the account's own live model list, points balance, newcomer rewards, invite codes.",
5
5
  "type": "module",
6
6
  "main": "./index.mjs",
@@ -366,7 +366,7 @@ function inviteTag(c) {
366
366
  }
367
367
 
368
368
 
369
- // ═══ 邀请上级:登录页一个按钮 + 一个数字文本框 ═══════════════════════
369
+ // ═══ 邀请码:登录页一个按钮 + 一个数字文本框 ═══════════════════════
370
370
  //
371
371
  // 用户要的是「一个文本框就够」:
372
372
  // 0 / 留空 / 非法文本 = 自动(首次用作者码,之后跟随最后登录/签到的滚动码)
@@ -389,8 +389,33 @@ function preferredInvite(c) {
389
389
  }
390
390
  }
391
391
 
392
- function inviteMessage(c) {
393
- return "邀请上级:自动=0;首选=1;不填=默认自动"
392
+ function modeHint(c) {
393
+ const pol = readInvitePolicy(c.id)
394
+ if (pol.mode === "auto" || !pol.code) return "当前模式:自动,输入 1 切换:首选"
395
+ const pref = preferredOrg(c.id)
396
+ const preferred = pol.mode === "fixed" && pref && pol.org === pref
397
+ return `当前模式:${preferred ? "首选" : "固定"},输入 0 切换:自动`
398
+ }
399
+
400
+ function invitePrompt(c) {
401
+ return { type: "text", key: "invite", message: "邀请码", placeholder: modeHint(c) }
402
+ }
403
+
404
+ function saveInviteChoice(c, raw) {
405
+ const n = String(raw ?? "").trim() === "" ? 0 : Number(String(raw).trim())
406
+ if (n === 1) {
407
+ const pick = preferredInvite(c)
408
+ if (pick) {
409
+ writeInvitePolicy(c.id, {
410
+ mode: "fixed",
411
+ code: pick.code,
412
+ org: pick.org,
413
+ accountId: pick.accountId,
414
+ })
415
+ return
416
+ }
417
+ }
418
+ writeInvitePolicy(c.id, { mode: "auto" })
394
419
  }
395
420
 
396
421
  export function makeMethods(c) {
@@ -403,10 +428,11 @@ export function makeMethods(c) {
403
428
  // 国际站回 `1000 请求成功`。
404
429
  // 国内站既然没有邮箱入口,也就不存在邮箱注册的账号 —— 把这条方法摆出来,
405
430
  // 只会让用户填完邮箱撞一个看不懂的错。
431
+ const mobileMethod = makeCodeMethod(c, "mobile")
406
432
  const codeMethods =
407
433
  c.id === "magicrew-intl"
408
- ? [makeCodeMethod(c, "email"), makeCodeMethod(c, "mobile")]
409
- : [makeCodeMethod(c, "mobile")]
434
+ ? [makeCodeMethod(c, "email"), mobileMethod]
435
+ : [mobileMethod]
410
436
 
411
437
  return [
412
438
  ...codeMethods,
@@ -631,42 +657,24 @@ export function makeMethods(c) {
631
657
  },
632
658
  },
633
659
 
634
- // ── 邀请上级:只存设置、不登录;一个数字文本框 ────────────────
660
+ // ── 邀请码:一个数字框;保存后直接接手机号验证码 ─────────────
661
+ //
662
+ // 0/留空 = 自动(首次作者码,之后滚动最新号);1 = 当前首选账号。
663
+ // 保存写在手机验证码**之前**:接下来无论走哪条登录,注册时读到的都是这个模式。
635
664
  {
636
- type: "api",
637
- keyless: true,
638
- label: `${c.SHORT} 邀请上级`,
639
- // getter:每次 magpie 取 prompts(点开登录方式时)都按当时滚动码/账号清单重新生成,
640
- // 不是插件加载时那一份
665
+ type: "oauth",
666
+ label: `${c.SHORT} 邀请码`,
641
667
  get prompts() {
642
- return [{ type: "text", key: "invite", message: inviteMessage(c), placeholder: "0" }]
668
+ return [invitePrompt(c)]
643
669
  },
644
670
  async ask(inputs) {
645
- if (inputs && Object.prototype.hasOwnProperty.call(inputs, "invite")) return null
646
- return { type: "text", key: "invite", message: inviteMessage(c), placeholder: "0" }
671
+ if (!inputs || !Object.prototype.hasOwnProperty.call(inputs, "invite")) return invitePrompt(c)
672
+ if (!Object.prototype.hasOwnProperty.call(inputs, "phone")) return mobileMethod.prompts[0]
673
+ return null
647
674
  },
648
675
  async authorize(inputs) {
649
- const raw = String(inputs?.invite ?? "").trim()
650
- const n = raw === "" ? 0 : Number(raw)
651
- if (n === 1) {
652
- const pick = preferredInvite(c)
653
- if (pick) {
654
- writeInvitePolicy(c.id, {
655
- mode: "fixed",
656
- code: pick.code,
657
- org: pick.org,
658
- accountId: pick.accountId,
659
- })
660
- return {
661
- type: "failed",
662
- error: `已保存:新号挂在首选 ${pick.label}(${pick.code})。这一步只存设置,不登录、不新增账号。`,
663
- }
664
- }
665
- writeInvitePolicy(c.id, { mode: "auto" })
666
- return { type: "failed", error: "当前没有可用的首选账号邀请码,已回退 0(自动)。" }
667
- }
668
- writeInvitePolicy(c.id, { mode: "auto" })
669
- return { type: "failed", error: "已保存:0 = 自动(新号跟随当前滚动码)。这一步只存设置,不登录、不新增账号。" }
676
+ saveInviteChoice(c, inputs?.invite)
677
+ return await mobileMethod.authorize(inputs)
670
678
  },
671
679
  },
672
680
  ]