magicrew-auth 0.3.36 → 0.3.38

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/README.md CHANGED
@@ -34,7 +34,7 @@
34
34
  - **默认开启自动签到** —— 安装后自动把本 provider 的插件签到设为开(`pluginCheckins` 缺省时补 true;你手动关掉的不会被改回)
35
35
  - **自动更新** —— 复用 magpie 的插件更新机制:发现自己的新版本后调 `magpie plugin update`,并在成功后写「已自动更新」记录;更新完要重启一次 magpie 才会加载新代码
36
36
  - **邀请码自动滚** —— 第一次注册带作者的码,之后每次登录都记住「上一个登录账号」的码,拿到新的就覆盖旧的
37
- - **邀请上级可固定** —— 登录页多一个按钮「邀请上级」:填数字,0=我的(作者 MYCF711),1..N=已登录账号(按账号名排序),-1=自动(跟随滚动);留空 / 不存在的数字回退 0。对照表在提示里,保存后回一条说明
37
+ - **邀请上级可固定** —— 登录页多一个按钮「邀请上级」:填数字,0=自动(当前滚动码,显示归属账号;没有滚动码时显示作者 MYCF711),1..N=已登录账号;留空 / 非法文本回退 0。对照表在提示里,保存后回一条说明
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.36",
3
+ "version": "0.3.38",
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",
@@ -30,6 +30,7 @@ import {
30
30
  } from "../api.mjs"
31
31
  import {
32
32
  inviteToUse,
33
+ readInvite,
33
34
  liveOrgs,
34
35
  authorInvite,
35
36
  readAccountCodes,
@@ -378,25 +379,52 @@ function inviteTag(c) {
378
379
  // 用 ask(而不是静态 prompts)是为了每次打开都按最新账号清单生成对照表 ——
379
380
  // 插件加载时 backfill 可能还没跑完。
380
381
 
381
- function inviteEntries(c) {
382
- const out = []
382
+ function inviteZero(c) {
383
+ const codes = readAccountCodes(c.id)
383
384
  const author = authorInvite(c.id)
384
- if (author) out.push({ n: 0, label: "我的(作者 MYCF711)", code: author, org: "", accountId: "MYCF711" })
385
+ const rolling = readInvite(c.id)
386
+ const code = rolling || author
387
+ // 0 = 老的滚动规则最新那个码;找到归属就显示账号名,否则退作者码
388
+ if (rolling && code !== author) {
389
+ const owner = Object.keys(codes).find((o) => codes[o]?.code === code)
390
+ if (owner) {
391
+ const accountId = String(codes[owner].accountId || owner)
392
+ return { code, label: accountId, org: owner, accountId }
393
+ }
394
+ return { code, label: "自动(滚动)", org: "", accountId: "" }
395
+ }
396
+ return { code: author, label: "自动(作者 MYCF711)", org: "", accountId: "MYCF711" }
397
+ }
398
+
399
+ function inviteEntries(c) {
385
400
  const codes = readAccountCodes(c.id)
386
- const rows = Object.entries(codes)
387
- .filter(([, v]) => v?.code && v.code !== author)
388
- .sort((a, b) => String(a[1].accountId || a[0]).localeCompare(String(b[1].accountId || b[0]), "zh"))
389
- for (const [org, v] of rows) {
390
- out.push({ n: out.length, label: String(v.accountId || org), code: v.code, org, accountId: String(v.accountId || org) })
401
+ const author = authorInvite(c.id)
402
+ const live = liveOrgs(c.id)
403
+ const out = []
404
+ let n = 1
405
+ for (const [org, v] of Object.entries(codes)) {
406
+ if (!v?.code || v.code === author) continue
407
+ if (live && live.size && !live.has(org)) continue
408
+ out.push({
409
+ n: n++,
410
+ label: String(v.accountId || org),
411
+ code: v.code,
412
+ org,
413
+ accountId: String(v.accountId || org),
414
+ })
391
415
  }
392
416
  return out
393
417
  }
394
418
 
395
419
  function inviteMessage(c) {
396
- const entries = inviteEntries(c)
397
- const parts = ["邀请上级:填数字后点下一步", "-1 = 自动(跟随最后一个登录 / 签到的号)"]
398
- for (const e of entries) parts.push(`${e.n} = ${e.label}(${e.code})`)
399
- parts.push("留空 / 不存在的数字 = 0")
420
+ const zero = inviteZero(c)
421
+ const parts = ["邀请上级:填数字后点下一步", `0 = ${zero.label}(${zero.code})`]
422
+ for (const e of inviteEntries(c)) {
423
+ // 0 指向的那个账号在 1..N 里也有一格,但当前不显示(换了 0 就露出来)
424
+ if (e.code === zero.code) continue
425
+ parts.push(`${e.n} = ${e.label}(${e.code})`)
426
+ }
427
+ parts.push("留空 / 非法文本 = 0")
400
428
  return parts.join(";")
401
429
  }
402
430
 
@@ -650,19 +678,23 @@ export function makeMethods(c) {
650
678
  },
651
679
  async authorize(inputs) {
652
680
  const raw = String(inputs?.invite ?? "").trim()
653
- const n = raw === "" ? 0 : Number(raw)
654
- if (n === -1) {
681
+ let n = raw === "" ? 0 : Number(raw)
682
+ if (!Number.isInteger(n) || n < 0) n = 0
683
+ if (n === 0) {
655
684
  writeInvitePolicy(c.id, { mode: "auto" })
656
- return { type: "failed", error: "已保存:自动(新号跟随最后一个登录 / 签到的号)。这一步只存设置,不登录、不新增账号。" }
685
+ return { type: "failed", error: "已保存:0 = 自动(新号跟随当前滚动码)。这一步只存设置,不登录、不新增账号。" }
657
686
  }
658
687
  const entries = inviteEntries(c)
659
- if (!entries.length) return { type: "failed", error: "没有可用的邀请码(还没登录过账号)" }
660
- const pick = Number.isInteger(n) && n >= 0 ? entries[n] ?? entries[0] : entries[0]
688
+ const pick = entries.find((e) => e.n === n)
689
+ if (!pick) {
690
+ writeInvitePolicy(c.id, { mode: "auto" })
691
+ return { type: "failed", error: "数字没有对应账号,已回退 0(自动)。这一步只存设置,不登录、不新增账号。" }
692
+ }
661
693
  writeInvitePolicy(c.id, {
662
694
  mode: "fixed",
663
695
  code: pick.code,
664
- org: pick.n === 0 ? "" : pick.org,
665
- accountId: pick.n === 0 ? "MYCF711" : pick.accountId,
696
+ org: pick.org,
697
+ accountId: pick.accountId,
666
698
  })
667
699
  return {
668
700
  type: "failed",