magicrew-auth 0.3.14 → 0.3.15

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/CHANGELOG.md CHANGED
@@ -1,5 +1,57 @@
1
1
  # 更新记录
2
2
 
3
+ ## 0.3.15
4
+
5
+ **修掉「网页已经登好、magpie 里一直转圈等」—— 弹窗永远拉不起来**
6
+
7
+ 现象:点「浏览器登录」,浏览器里登完了、跳到 agent 界面了,magpie 的卡片一直停在
8
+ 「请在浏览器中完成登录」,直到 5 分钟超时。
9
+
10
+ 根因在 `~/.cache/magpie/magicrew-login-<site>.log` 里躺着,每次都是同一行:
11
+
12
+ ```
13
+ launch: 本机没找到 Chrome / Edge / Bravo / Chromium
14
+ ```
15
+
16
+ **这台机器上 Edge 是装着的**(122.0.2365.106,微软官方包)。`findBrowser()` 写死的
17
+ 文件名是 `msedge.exe`,但这台机器上微软落盘的名字是 **`Microsoft Edge.exe`**
18
+ (带空格、带大写)—— 而另一台机器的 156 版只有 `msedge.exe`。**落盘名随安装方式/版本变**,
19
+ 写死任何一个都必有一类机器命中不到。`existsSync` 一路 miss → 返回 `null` →
20
+ 永远走「降级到系统浏览器 + 让用户去 Console 粘一行」。用户看到的就是「登好了但插件还在等」。
21
+
22
+ 顺带两件事:
23
+
24
+ - **国产 Chromium 系一个都没列**。用户日常用的是 360 极速浏览器 X(360ChromeX,
25
+ Chrome 132 内核),实测 `--remote-debugging-port=0` + CDP `Runtime.evaluate`
26
+ 完全可用 —— 没有任何理由不支持。
27
+ - **只挑「第一个存在的」**,一旦那个起不来就彻底失败。改成**逐个试**,
28
+ 第一个真写出 `DevToolsActivePort` 的才算数;全失败时把每个候选的失败原因都带出来。
29
+
30
+ ### 浏览器优先级(按「谁最干净」排,不是按名气)
31
+
32
+ ```
33
+ ① Chrome / Chromium 自己装的,无企业策略、无强制登录 ← 首选
34
+ ② 国产 Chromium 系 用户日常在用的,CDP 实测一样能用
35
+ ③ Edge 垫底:策略最多、最容易被拦、且用户明确不想用它
36
+ ```
37
+
38
+ 本机实测(Chromium 154.0.8037.93,scoop 安装):**起 CDP 650–800ms,页面就绪 ~2s,
39
+ `waitForCreds` 正常读到凭据,关窗后 profile 彻底删除。**
40
+
41
+ - `findBrowser()` 改为返回 `{ name, path }`(原来是裸字符串),新增 `browserCandidates()`
42
+ - 新增 scoop / 便携版 Chromium 路径(本机就是 scoop 装的那条)
43
+ - `waitPort()` 支持「进程已退出就别白等 8 秒」的提前放弃
44
+ - `launchLoginBrowser()` 返回体新增 `name` / `exe`,卡片文案会写明用的是哪个浏览器
45
+ - `local-browser.mjs` 的 `roots()` 补上 360 / QQ / 搜狗等,让「本机已登录就直接认」也能命中
46
+ - 判据:`node tests/browser-detect.mjs`(Edge 真实文件名 / 国产覆盖 / Chromium 优先 / 逐个试)
47
+
48
+ ### 为什么先修「怎么把窗口拉起来」,而不是去补更多登录方式
49
+
50
+ 这条链只有一个出口:**窗口拉不起来,后面的 CDP 读取一步都走不到**。
51
+ 0.3.12 及更早的失败还是**静默**的 —— 它会「成功」降级到剪贴板通道,而那一步要求
52
+ 用户知道有 F12 这回事。所以症状不是「报错」,而是「看起来什么都没发生」。
53
+ 判据落在 `magicrew-login-<site>.log` 里,就是为了这种静默失败下次能一眼看见。
54
+
3
55
  ## 0.3.14
4
56
 
5
57
  **两处判据修正:国际站看「话题」而不是「项目」;「免费」不再从倍率反推**
@@ -91,6 +143,7 @@ magicrew#g8rptf (66p0q…) first_ai_work PENDING/PENDING → COMPLETED/GRANTE
91
143
  再调一次 `ensureFirstTaskOnce` 直接返回 `{ settled: true }`:不打网络、不发消息,
92
144
  一次性闸门生效。
93
145
 
146
+
94
147
  ## 0.3.12
95
148
 
96
149
  **插件不再写 magpie 自己的缓存**
package/README.md CHANGED
@@ -1,208 +1,222 @@
1
- # 超级麦吉 / MagiCrew for magpie
2
-
3
- **一个包,两个供应商:国内的 GLM / DeepSeek / Qwen / Kimi,国际再加 Claude / GPT / Gemini —— 原样走它的 OpenAI 兼容网关。**
4
-
5
- 超级麦吉(`letsmagic.cn`)和 MagiCrew(`magicrew.ai`)是同一产品的两套云。这个插件把它们各接成一个独立供应商 —— 在 magpie 的供应商列表、用量概览、模型目录里各占一行,不聚合、不互相覆盖登录态。
6
-
7
- ```
8
- 国内 超级麦吉 www.letsmagic.cn GLM / DeepSeek / Qwen / Kimi / MiniMax / MiMo / 豆包
9
- 国际 MagiCrew www.magicrew.ai 上面全部,再加 Claude / GPT / Gemini
10
- 协议 OpenAI Chat Completions —— 原生,不是翻译出来的
11
- 计费 积分(预充值,不是月度配额)
12
- 凭证 登录一次 30 天全自动:api_key 两小时自续,refresh_token 自滚
13
- ```
14
-
15
- > 上面那排是 2026-10-27 从两站 `GET /api/v1/flows/models` 拉下来核对的。清单会随订阅档位和平台上下架变 —— 所以插件里**没有一张写死的模型清单**,账户能选什么就显示什么。
16
-
17
- ---
18
-
19
- ## 功能
20
-
21
- - **两个供应商分得开** —— 国内、国际各一行,图标、名字、模型、积分、登录态全部独立
22
- - **本机浏览器登过就直接认** —— 你平时那个 Edge / Chrome / Brave 里登过 magicrew,点登录时插件读它的 localStorage 接上:不开窗口、不用重登
23
- - **模型跟着账号走** —— 每次登录后按 `/api/v1/flows/models` 实时拉,账户当前能选什么就展示什么,生图和 embedding 不会混进来
24
- - **积分算得准** —— 余额读的是 `/api/v1/quota/points/total`;空号就显示空,不会被优先派活
25
- - **登录一次管 30 天** —— 网页 JWT 顶 30 天,`mgw_` api_key 每 2 小时自续,refresh_token 每次续期时自滚
26
- - **点一下,全自动** —— 插件自己拉起浏览器停在官方登录页,你在里面登(手机号 / 密码 / Google / 邮箱验证码 / 飞书 / 钉钉都行),登录完成那一刻它自己把凭据读走,不用回来点任何东西
27
- - **登录方式还有两条备选** —— 手机号+密码走 API;或者直接粘 JWT + 组织码
28
- - **新手奖励自动领** —— 国内站 8 项里 7 项 PUT 即到账,每天跑一次幂等
29
- - **邀请码自动滚** —— 第一次注册带作者的码,之后每次登录都记住「上一个登录账号」的码,拿到新的就覆盖旧的
30
-
31
- ---
32
-
33
- ## 模型
34
-
35
- **国内的 GLM、DeepSeek、Qwen、Kimi、MiniMax、MiMo、豆包;国际站再加 Claude、GPT、Gemini 三家。**
36
-
37
- 登录后按账号实时拉 `/api/v1/flows/models`,账户能选什么就显示什么 —— 下表只列各家**最新**和**热门**的那几款:
38
-
39
- | 发行商 | 最新 / 热门 | 上下文 | 国内 | 国际 |
40
- |---|---|---|---|---|
41
- | GLM(智谱) | `glm-5.3` · `glm-5.3-flash` | 1M · 256K | ✓ | ✓ |
42
- | DeepSeek | `deepseek-v4.1-flash` | 1M | ✓ | ✓ |
43
- | DeepSeek | `deepseek-v4-pro` | 128K | — | ✓ |
44
- | Qwen(阿里) | `qwen3.8-max` · `qwen3.7-plus` | 1M | ✓ | ✓ |
45
- | Kimi(月之暗面) | `kimi-k3.1-pro` | 1M | ✓ | ✓ |
46
- | MiniMax | `minimax-m3` · `minimax-m3.1-flash` | 1M | ✓ | ✓ |
47
- | MiMo(小米) | `mimo-v2.6-pro` · `mimo-v2.6-flash` | 1M | ✓ | ✓ |
48
- | 豆包 Seed(字节) | `doubao-seed-2.0-pro` · `doubao-seed-2.0-code` | 256K | ✓ | ✓ |
49
- | Claude(Anthropic) | `claude-haiku-5.5` | 1M | — | ✓ |
50
- | GPT(OpenAI) | `gpt-6-luna` · `gpt-5.4-mini` | 1.05M · 400K | — | ✓ |
51
- | Gemini(Google) | `gemini-3.7-flash` | 1M | — | ✓ |
52
-
53
- 全量(含生图、向量、各家历史版本)不进 README —— 装好以后模型选择器里看到的才是账号真实的全部。
54
-
55
- 用的是 `/api/v1/flows/models`(网页模型选择器里眼睛能点到的那些),不是 `/v1/models` —— 后者混着 VIP 锁定、生图、embedding,塞进来用户会选到根本调不动的模型。
56
-
57
- 上下文按三档取:magpie GUI 里手选 > 模型库(`~/.cache/magpie/models.json`)> 兜底 1M。这两个接口都不返回 `context_length`;早先一律填 256K,把 `deepseek-v4.1-flash` 真实 1M 的窗口砍成四分之一,agent 反而更早拒绝 —— 根因与取舍见 `docs/internals.md` 第十六节。
58
-
59
- 推理模型会吃 `max_tokens`:`glm-5.3-flash` 给 64 个 token 时 `reasoning_content` 就吃满、`content` 是空串。插件把低于 512 的 `max_tokens` 抬到 512。
60
-
61
- 两站不是简单叠加:国际站多出 Claude / GPT / Gemini 三家,另有豆包 Seed 1.8 / 2.0-mini / seed-code、Kimi K2.6 / K2.7-code / K3、GLM 5.2、Qwen3.7-max 这些国内没有的档位。
62
-
63
- ---
64
-
65
- ## 新手奖励
66
-
67
- 国内站 8 项任务合计 500 积分,7 项 PUT 一次就完成(实测 1240 → 1540,+300,六项当场入账)。只有「完成第一次 AI 工作」那项服务端认死必须真的跑过一次,PUT 回 `9303`。
68
-
69
- 国际站 `/api/v1/onboarding/tasks` 现在返回空列表 —— 接口在,这个账号没东西可领。
70
-
71
- 每天跑一次,幂等。
72
-
73
- ---
74
-
75
- ## 邀请码
76
-
77
- 只一条规则,不需要你选任何东西:
78
-
79
- ```
80
- ① 固定位置有记录 → 用记录里那个
81
- ② 没有记录 → 用作者的码
82
- ③ 登录成功后 → 查这个账号自己的码 → 覆盖写回
83
- ```
84
-
85
- 效果:第一次注册带作者的码,之后每次都用「上一个登录成功的账号」的码,一路滚下去。
86
-
87
- 固定位置:
88
-
89
- ```
90
- ~/.cache/magpie/magicrew-invite-<站点 id>.json {"code":"...","at":"..."}
91
- ```
92
-
93
- > ③ 不是每次都能成。`/api/v1/invitations/info` 只认带 `device_id` 的 JWT —— 同一个账号同一时刻签的两把,差别就在这一个字段:桌面客户端 438 字符(`device_id` = 64 位 hex)能拿到码,网页版 350 字符(`device_id` 空)回 `2155 用户不存在`。
94
- > 密码登录走 API、带 device 指纹,滚得动;浏览器登录拿到的是网页那把,滚不动 —— 那就保留旧值,不报错、不挡登录。
95
-
96
- 奖励口径(上游前端常量,2026-10-27):
97
-
98
- | | 每次注册 | 每次订阅 | 邀请注册封顶 | 总额封顶 |
99
- |---|---|---|---|---|
100
- | 国内 | 1,000 | 3,000 | 60,000 | 300,000 |
101
- | 国际 | 200 | 500 | 10,000 | 30,000 |
102
-
103
- ---
104
-
105
- ## 安装
106
-
107
- 在 magpie 的 **插件 → 发现** 搜 `magicrew`,点**安装**(npm 上的包名是 `magicrew-auth`)。
108
-
109
- 装完选站点,然后**点第一个「浏览器登录」**。它先看你平时用的那个浏览器:
110
-
111
- **① 那边已经登录过 magicrew** → 插件直接读它的 localStorage 接上,**不开窗口、不用再登一次**。
112
- 凭据就明文躺在 `Local Storage/leveldb` 里(Edge / Chrome / Brave / Chromium 都行)。
113
-
114
- **② 没登录过,或者这个账号已经加过** → 插件自己拉起一个窗口:
115
-
116
- 1. 浏览器窗口弹出,停在官方登录页
117
- 2. 用你平时的方式登进去(手机号 / 密码 / Google / 邮箱验证码 / 飞书 / 钉钉都行)
118
- 3. **登录完成那一刻它自己就接上了** —— 不用回来点任何按钮,不用开 DevTools
119
-
120
- 原理:插件不是调用系统浏览器,而是自己起一个 Edge / Chrome(独立 profile +
121
- `--remote-debugging-port`),所以登录成功后能用 CDP 在页面上下文里把它自己的
122
- localStorage 读走,拿到 JWT 和组织码,签完密钥就关窗。
123
-
124
- **每次登录都是一个新的 profile,用完就删。** 这是必须的:共用一个 profile 的话,
125
- 添加第二个账号时窗口一打开,页面里已经躺着上一个账号的凭据 —— 插件会以为登录完成、
126
- 立刻关窗,而 magpie 拿到的还是旧账号(同账号 → 替换,不新增)。
127
-
128
- > **为什么两条路都要?** magicrew 没有 OAuth 回调通道 —— 登录类型只有 13 种、全是「拿凭据换 token」,没有设备码、没有插件授权、没有一次性 ticket。凭据只可能落在两个地方:你自己浏览器的 localStorage(插件读文件就能拿到,所以优先),或者插件自己起的那个窗口(读不到时才需要)。
129
- >
130
- > 本机没装 Chrome / Edge 时自动降级:改用系统浏览器打开,登录完把凭证送进剪贴板,插件从剪贴板读。
131
-
132
- 不想碰 Console 的话,另外两条:
133
-
134
- - **密码登录** —— 手机号 + 密码 + 区号,走 API,全程在 magpie 里
135
- - **登录态(JWT + 组织码)** —— 手填两个字段:
136
-
137
- ```
138
- DevTools → Application → Local Storage → https://www.magicrew.ai
139
- MAGIC:user:authorization → JSON,取 value = JWT
140
- MAGIC:user:organizationCode → JSON,取 value = 组织码(12 位小写字母数字)
141
- ```
142
-
143
- > 组织码**不能从 JWT 推**。JWT 里只有 `cus.tenant_id`(18 位数字),组织码是另一套短串。缺了它 `/api/v1/*` 回 `2182 用户所在组织不存在`,给错了回 `3035 登录失败`。
144
-
145
- ### 命令行
146
-
147
- ```bash
148
- # npm(推荐:magpie 按 version 检测更新,有新版本会提示)
149
- magpie plugin add magicrew-auth
150
-
151
- # 从仓库源码(拿最新提交,不走 npm;更新按 commit,要手动 update)
152
- magpie plugin add github:MYCF711/magpie-magicrew-auth
153
- ```
154
-
155
- > **两条路的卡片标题不一样**:npm 装 → 卡片标题就是包名 `magicrew-auth`;git 装 → 取 `package.json` 的 `name`,也就是 **`Magicrew`**。功能一样,只是标题。
156
- > 从旧包名 `magpie-magicrew-auth` 过来的,先 `magpie plugin rm magpie-magicrew-auth` 再装。
157
-
158
- 装完确认:
159
-
160
- ```bash
161
- magpie plugin list
162
- # magicrew-auth on
163
- # magicrew (超级麦吉, 27 models) signed in as ...
164
- # magicrew-intl (MagiCrew, 49 models) signed in as ...
165
- ```
166
-
167
- 两个供应商各一行 —— 这就是「不聚合」的样子。
168
-
169
- ---
170
-
171
- ## 常见问题
172
-
173
- **两个站要装两次吗?** 不用。一个包导出两个插件,装一次两个供应商都在,各自登录。
174
-
175
- **我在自己浏览器里登了 magicrew,插件能自动认出来吗?** 能。点「浏览器登录」时插件先去本机 Edge / Chrome / Brave / Chromium 的 localStorage 里找**这个站点**的登录态,找到就直接接上,不弹窗口。读不到、或者这个账号已经加过,才会开窗口让你登新的。
176
-
177
- **添加第二个账号时,网页闪一下就关了、magpie 里也没多出账号?** 0.3.5 及更早会这样:登录浏览器复用同一个 profile,第二个窗口一打开就读到上一个账号的凭据,于是立刻「登录成功」并关窗 —— 加到的是已有账号。0.3.6 起每次登录用一个一次性 profile(关窗即删),不会再串号。
178
-
179
- **npm 上叫 `magicrew-auth`,为什么卡片显示 `Magicrew`?** 卡片标题取包内 `package.json` 的 `name`(`Magicrew`),而 npm 拒绝含大写字母的新包名。发布时用 `publish-npm.mjs` 临时换成 `magicrew-auth`、发完还原 —— 所以 npm 页面是小写包名,git 源装出来是 `Magicrew`。功能完全一样。
180
-
181
- **为什么模型列表会变?** 因为清单是从 `/api/v1/flows/models` 实时拉的。订阅档位变了、平台方上下架变了,清单就跟着变 —— 插件里没有需要维护的模型表。
182
-
183
- **国际站 `/v1/chat/completions` 报 500,22 字节的纯文本?** 那是缺 `organization-code` 请求头。国内站不需要,国际站强制。插件按站点自动带。
184
-
185
- **`glm-5.3-flash` 回复是空的?** 推理 token 吃满了 `max_tokens`。插件已经把低于 512 的抬到 512;还是空就把 `max_tokens` 再调大。
186
-
187
- **Android / macOS 也支持吗?** 插件只调 HTTP 接口,跟客户端无关。设备上能登录,这里就能用。
188
-
189
- ---
190
-
191
- ## 参考源
192
-
193
- | 来源 | 用在哪 |
194
- |---|---|
195
- | [dtyq/magic](https://github.com/dtyq/magic)(Apache 2.0 + 附加限制) | 接口契约:`types/login.ts` 的 `invite_code`、`LoginService.ts` 关于「邀请码在创建组织时消费」的注释、`constants/api.ts` 的错误码 |
196
- | [@magpie-community/opencode-workbuddy-auth](https://github.com/magpie-community/plugins/tree/main/packages/workbuddy)(MIT) | 「一个包导出多个 `XxxAuthPlugin`」的写法:每个站点一个具名导出,各成一个供应商 |
197
- | [@magpie-community/opencode-qoder-auth](https://github.com/magpie-community/plugins/tree/main/packages/qoder)(MIT) | 同上,四站点四导出的对照例 |
198
- | [magpie-plugin-template](https://github.com/MYCF711/magpie-plugin-template)(MIT) | README / CHANGELOG / NOTICE 的骨架与硬规则 |
199
-
200
- 本插件不复制上游代码,只调它的公开 HTTP 接口。完整版权声明见 [`NOTICE.md`](./NOTICE.md)。
201
-
202
- ---
203
-
204
- > 更新记录:[`CHANGELOG.md`](./CHANGELOG.md)
205
-
206
- ## 许可
207
-
208
- MIT。
1
+ # 超级麦吉 / MagiCrew for magpie
2
+
3
+ **一个包,两个供应商:国内的 GLM / DeepSeek / Qwen / Kimi,国际再加 Claude / GPT / Gemini —— 原样走它的 OpenAI 兼容网关。**
4
+
5
+ 超级麦吉(`letsmagic.cn`)和 MagiCrew(`magicrew.ai`)是同一产品的两套云。这个插件把它们各接成一个独立供应商 —— 在 magpie 的供应商列表、用量概览、模型目录里各占一行,不聚合、不互相覆盖登录态。
6
+
7
+ ```
8
+ 国内 超级麦吉 www.letsmagic.cn GLM / DeepSeek / Qwen / Kimi / MiniMax / MiMo / 豆包
9
+ 国际 MagiCrew www.magicrew.ai 上面全部,再加 Claude / GPT / Gemini
10
+ 协议 OpenAI Chat Completions —— 原生,不是翻译出来的
11
+ 计费 积分(预充值,不是月度配额)
12
+ 凭证 登录一次 30 天全自动:api_key 两小时自续,refresh_token 自滚
13
+ ```
14
+
15
+ > 上面那排是 2026-10-27 从两站 `GET /api/v1/flows/models` 拉下来核对的。清单会随订阅档位和平台上下架变 —— 所以插件里**没有一张写死的模型清单**,账户能选什么就显示什么。
16
+
17
+ ---
18
+
19
+ ## 功能
20
+
21
+ - **两个供应商分得开** —— 国内、国际各一行,图标、名字、模型、积分、登录态全部独立
22
+ - **本机浏览器登过就直接认** —— 你平时那个 Edge / Chrome / Brave 里登过 magicrew,点登录时插件读它的 localStorage 接上:不开窗口、不用重登
23
+ - **模型跟着账号走** —— 每次登录后按 `/api/v1/flows/models` 实时拉,账户当前能选什么就展示什么,生图和 embedding 不会混进来
24
+ - **积分算得准** —— 余额读的是 `/api/v1/quota/points/total`;空号就显示空,不会被优先派活
25
+ - **登录一次管 30 天** —— 网页 JWT 顶 30 天,`mgw_` api_key 每 2 小时自续,refresh_token 每次续期时自滚
26
+ - **点一下,全自动** —— 插件自己拉起浏览器停在官方登录页,你在里面登(手机号 / 密码 / Google / 邮箱验证码 / 飞书 / 钉钉都行),登录完成那一刻它自己把凭据读走,不用回来点任何东西
27
+ - **登录方式还有两条备选** —— 手机号+密码走 API;或者直接粘 JWT + 组织码
28
+ - **新手奖励自动领** —— 国内站 8 项里 7 项 PUT 即到账,每天跑一次幂等
29
+ - **邀请码自动滚** —— 第一次注册带作者的码,之后每次登录都记住「上一个登录账号」的码,拿到新的就覆盖旧的
30
+
31
+ ---
32
+
33
+ ## 模型
34
+
35
+ **国内的 GLM、DeepSeek、Qwen、Kimi、MiniMax、MiMo、豆包;国际站再加 Claude、GPT、Gemini 三家。**
36
+
37
+ 登录后按账号实时拉 `/api/v1/flows/models`,账户能选什么就显示什么 —— 下表只列各家**最新**和**热门**的那几款:
38
+
39
+ | 发行商 | 最新 / 热门 | 上下文 | 国内 | 国际 |
40
+ |---|---|---|---|---|
41
+ | GLM(智谱) | `glm-5.3` · `glm-5.3-flash` | 1M · 256K | ✓ | ✓ |
42
+ | DeepSeek | `deepseek-v4.1-flash` | 1M | ✓ | ✓ |
43
+ | DeepSeek | `deepseek-v4-pro` | 128K | — | ✓ |
44
+ | Qwen(阿里) | `qwen3.8-max` · `qwen3.7-plus` | 1M | ✓ | ✓ |
45
+ | Kimi(月之暗面) | `kimi-k3.1-pro` | 1M | ✓ | ✓ |
46
+ | MiniMax | `minimax-m3` · `minimax-m3.1-flash` | 1M | ✓ | ✓ |
47
+ | MiMo(小米) | `mimo-v2.6-pro` · `mimo-v2.6-flash` | 1M | ✓ | ✓ |
48
+ | 豆包 Seed(字节) | `doubao-seed-2.0-pro` · `doubao-seed-2.0-code` | 256K | ✓ | ✓ |
49
+ | Claude(Anthropic) | `claude-haiku-5.5` | 1M | — | ✓ |
50
+ | GPT(OpenAI) | `gpt-6-luna` · `gpt-5.4-mini` | 1.05M · 400K | — | ✓ |
51
+ | Gemini(Google) | `gemini-3.7-flash` | 1M | — | ✓ |
52
+
53
+ 全量(含生图、向量、各家历史版本)不进 README —— 装好以后模型选择器里看到的才是账号真实的全部。
54
+
55
+ 用的是 `/api/v1/flows/models`(网页模型选择器里眼睛能点到的那些),不是 `/v1/models` —— 后者混着 VIP 锁定、生图、embedding,塞进来用户会选到根本调不动的模型。
56
+
57
+ 上下文按三档取:magpie GUI 里手选 > 模型库(`~/.cache/magpie/models.json`)> 兜底 1M。这两个接口都不返回 `context_length`;早先一律填 256K,把 `deepseek-v4.1-flash` 真实 1M 的窗口砍成四分之一,agent 反而更早拒绝 —— 根因与取舍见 `docs/internals.md` 第十六节。
58
+
59
+ 推理模型会吃 `max_tokens`:`glm-5.3-flash` 给 64 个 token 时 `reasoning_content` 就吃满、`content` 是空串。插件把低于 512 的 `max_tokens` 抬到 512。
60
+
61
+ 两站不是简单叠加:国际站多出 Claude / GPT / Gemini 三家,另有豆包 Seed 1.8 / 2.0-mini / seed-code、Kimi K2.6 / K2.7-code / K3、GLM 5.2、Qwen3.7-max 这些国内没有的档位。
62
+
63
+ ---
64
+
65
+ ## 新手奖励
66
+
67
+ 国内站 8 项任务合计 500 积分,7 项 PUT 一次就完成(实测 1240 → 1540,+300,六项当场入账)。只有「完成第一次 AI 工作」那项服务端认死必须真的跑过一次,PUT 回 `9303`。
68
+
69
+ 国际站 `/api/v1/onboarding/tasks` 现在返回空列表 —— 接口在,这个账号没东西可领。
70
+
71
+ 每天跑一次,幂等。
72
+
73
+ ---
74
+
75
+ ## 邀请码
76
+
77
+ 只一条规则,不需要你选任何东西:
78
+
79
+ ```
80
+ ① 固定位置有记录 → 用记录里那个
81
+ ② 没有记录 → 用作者的码
82
+ ③ 登录成功后 → 查这个账号自己的码 → 覆盖写回
83
+ ```
84
+
85
+ 效果:第一次注册带作者的码,之后每次都用「上一个登录成功的账号」的码,一路滚下去。
86
+
87
+ 固定位置:
88
+
89
+ ```
90
+ ~/.cache/magpie/magicrew-invite-<站点 id>.json {"code":"...","at":"..."}
91
+ ```
92
+
93
+ > ③ 不是每次都能成。`/api/v1/invitations/info` 只认带 `device_id` 的 JWT —— 同一个账号同一时刻签的两把,差别就在这一个字段:桌面客户端 438 字符(`device_id` = 64 位 hex)能拿到码,网页版 350 字符(`device_id` 空)回 `2155 用户不存在`。
94
+ > 密码登录走 API、带 device 指纹,滚得动;浏览器登录拿到的是网页那把,滚不动 —— 那就保留旧值,不报错、不挡登录。
95
+
96
+ 奖励口径(上游前端常量,2026-10-27):
97
+
98
+ | | 每次注册 | 每次订阅 | 邀请注册封顶 | 总额封顶 |
99
+ |---|---|---|---|---|
100
+ | 国内 | 1,000 | 3,000 | 60,000 | 300,000 |
101
+ | 国际 | 200 | 500 | 10,000 | 30,000 |
102
+
103
+ ---
104
+
105
+ ## 安装
106
+
107
+ 在 magpie 的 **插件 → 发现** 搜 `magicrew`,点**安装**(npm 上的包名是 `magicrew-auth`)。
108
+
109
+ 装完选站点,然后**点第一个「浏览器登录」**。它先看你平时用的那个浏览器:
110
+
111
+ **① 那边已经登录过 magicrew** → 插件直接读它的 localStorage 接上,**不开窗口、不用再登一次**。
112
+ 凭据就明文躺在 `Local Storage/leveldb` 里(Edge / Chrome / Chromium / Brave / 360 / QQ / 搜狗 都行)。
113
+
114
+ **② 没登录过,或者这个账号已经加过** → 插件自己拉起一个窗口:
115
+
116
+ 1. 浏览器窗口弹出,停在官方登录页
117
+ 2. 用你平时的方式登进去(手机号 / 密码 / Google / 邮箱验证码 / 飞书 / 钉钉都行)
118
+ 3. **登录完成那一刻它自己就接上了** —— 不用回来点任何按钮,不用开 DevTools
119
+
120
+ 原理:插件不是调用系统浏览器,而是自己起一个 Chromium 内核的浏览器(独立 profile +
121
+ `--remote-debugging-port=0`),所以登录成功后能用 CDP 在页面上下文里把它自己的
122
+ localStorage 读走,拿到 JWT 和组织码,签完密钥就关窗。
123
+
124
+ **用哪个浏览器?** 按「谁更干净」排,不是按名气:
125
+
126
+ ```
127
+ ① Chrome / Chromium 自己装的,无企业策略、无强制登录 ← 首选
128
+ ② 国产 Chromium 系 360 / QQ / 搜狗 / 2345 / 猎豹 / UC / 夸克
129
+ ③ Edge 垫底(策略最多、最容易被拦住调试端口)
130
+ ```
131
+
132
+ 前一个起不来(策略禁用调试端口、启动就退出)会自动换下一个,
133
+ **第一个真正打开调试通道的才算数**,不用你操心。
134
+ 窗口标题/提示里会写明这次用的是哪个。
135
+
136
+ **每次登录都是一个新的 profile,用完就删。** 这是必须的:共用一个 profile 的话,
137
+ 添加第二个账号时窗口一打开,页面里已经躺着上一个账号的凭据 —— 插件会以为登录完成、
138
+ 立刻关窗,而 magpie 拿到的还是旧账号(同账号 → 替换,不新增)。
139
+
140
+ > **为什么两条路都要?** magicrew 没有 OAuth 回调通道 —— 登录类型只有 13 种、全是「拿凭据换 token」,没有设备码、没有插件授权、没有一次性 ticket。凭据只可能落在两个地方:你自己浏览器的 localStorage(插件读文件就能拿到,所以优先),或者插件自己起的那个窗口(读不到时才需要)。
141
+ >
142
+ > 本机没有任何 Chromium 内核浏览器时自动降级:改用系统浏览器打开,登录完把凭证送进剪贴板,插件从剪贴板读。
143
+
144
+ 不想碰 Console 的话,另外两条:
145
+
146
+ - **密码登录** —— 手机号 + 密码 + 区号,走 API,全程在 magpie 里
147
+ - **登录态(JWT + 组织码)** —— 手填两个字段:
148
+
149
+ ```
150
+ DevTools → Application → Local Storage → https://www.magicrew.ai
151
+ MAGIC:user:authorization → JSON,取 value = JWT
152
+ MAGIC:user:organizationCode → JSON,取 value = 组织码(12 位小写字母数字)
153
+ ```
154
+
155
+ > 组织码**不能从 JWT 推**。JWT 里只有 `cus.tenant_id`(18 位数字),组织码是另一套短串。缺了它 `/api/v1/*` 回 `2182 用户所在组织不存在`,给错了回 `3035 登录失败`。
156
+
157
+ ### 命令行
158
+
159
+ ```bash
160
+ # npm(推荐:magpie 按 version 检测更新,有新版本会提示)
161
+ magpie plugin add magicrew-auth
162
+
163
+ # 从仓库源码(拿最新提交,不走 npm;更新按 commit,要手动 update)
164
+ magpie plugin add github:MYCF711/magpie-magicrew-auth
165
+ ```
166
+
167
+ > **两条路的卡片标题不一样**:npm 装 → 卡片标题就是包名 `magicrew-auth`;git 装 → 取 `package.json` 的 `name`,也就是 **`Magicrew`**。功能一样,只是标题。
168
+ > 从旧包名 `magpie-magicrew-auth` 过来的,先 `magpie plugin rm magpie-magicrew-auth` 再装。
169
+
170
+ 装完确认:
171
+
172
+ ```bash
173
+ magpie plugin list
174
+ # magicrew-auth on
175
+ # magicrew (超级麦吉, 27 models) signed in as ...
176
+ # magicrew-intl (MagiCrew, 49 models) signed in as ...
177
+ ```
178
+
179
+ 两个供应商各一行 —— 这就是「不聚合」的样子。
180
+
181
+ ---
182
+
183
+ ## 常见问题
184
+
185
+ **两个站要装两次吗?** 不用。一个包导出两个插件,装一次两个供应商都在,各自登录。
186
+
187
+ **我在自己浏览器里登了 magicrew,插件能自动认出来吗?** 能。点「浏览器登录」时插件先去本机 Edge / Chrome / Chromium / Brave / 360 / QQ / 搜狗 等浏览器的 localStorage 里找**这个站点**的登录态,找到就直接接上,不弹窗口。读不到、或者这个账号已经加过,才会开窗口让你登新的。
188
+
189
+ **点了「浏览器登录」,网页上明明登好并跳到 agent 界面了,magpie 里却一直转圈等?** 0.3.12 及更早会这样:插件拉起浏览器的判断依赖一个写死的文件名 `msedge.exe`,而有些机器上微软落盘的名字是 **`Microsoft Edge.exe`**(带空格、带大写;落盘名随安装方式和版本变),于是每次都判定「本机没装浏览器」,永远走「让你去 Console 粘一行」的降级路径 —— 而你不知道有这一步。0.3.15 起:两种落盘名都认、把 360 / QQ / 搜狗 等国产 Chromium 也纳入候选、并且逐个试启动(第一个真能开调试通道的才用)。判据在 `~/.cache/magpie/magicrew-login-<站点>.log`,出问题先看它最后一行。
190
+
191
+ **添加第二个账号时,网页闪一下就关了、magpie 里也没多出账号?** 0.3.5 及更早会这样:登录浏览器复用同一个 profile,第二个窗口一打开就读到上一个账号的凭据,于是立刻「登录成功」并关窗 —— 加到的是已有账号。0.3.6 起每次登录用一个一次性 profile(关窗即删),不会再串号。
192
+
193
+ **npm 上叫 `magicrew-auth`,为什么卡片显示 `Magicrew`?** 卡片标题取包内 `package.json` 的 `name`(`Magicrew`),而 npm 拒绝含大写字母的新包名。发布时用 `publish-npm.mjs` 临时换成 `magicrew-auth`、发完还原 —— 所以 npm 页面是小写包名,git 源装出来是 `Magicrew`。功能完全一样。
194
+
195
+ **为什么模型列表会变?** 因为清单是从 `/api/v1/flows/models` 实时拉的。订阅档位变了、平台方上下架变了,清单就跟着变 —— 插件里没有需要维护的模型表。
196
+
197
+ **国际站 `/v1/chat/completions` 报 500,22 字节的纯文本?** 那是缺 `organization-code` 请求头。国内站不需要,国际站强制。插件按站点自动带。
198
+
199
+ **`glm-5.3-flash` 回复是空的?** 推理 token 吃满了 `max_tokens`。插件已经把低于 512 的抬到 512;还是空就把 `max_tokens` 再调大。
200
+
201
+ **Android / macOS 也支持吗?** 插件只调 HTTP 接口,跟客户端无关。设备上能登录,这里就能用。
202
+
203
+ ---
204
+
205
+ ## 参考源
206
+
207
+ | 来源 | 用在哪 |
208
+ |---|---|
209
+ | [dtyq/magic](https://github.com/dtyq/magic)(Apache 2.0 + 附加限制) | 接口契约:`types/login.ts` 的 `invite_code`、`LoginService.ts` 关于「邀请码在创建组织时消费」的注释、`constants/api.ts` 的错误码 |
210
+ | [@magpie-community/opencode-workbuddy-auth](https://github.com/magpie-community/plugins/tree/main/packages/workbuddy)(MIT) | 「一个包导出多个 `XxxAuthPlugin`」的写法:每个站点一个具名导出,各成一个供应商 |
211
+ | [@magpie-community/opencode-qoder-auth](https://github.com/magpie-community/plugins/tree/main/packages/qoder)(MIT) | 同上,四站点四导出的对照例 |
212
+ | [magpie-plugin-template](https://github.com/MYCF711/magpie-plugin-template)(MIT) | README / CHANGELOG / NOTICE 的骨架与硬规则 |
213
+
214
+ 本插件不复制上游代码,只调它的公开 HTTP 接口。完整版权声明见 [`NOTICE.md`](./NOTICE.md)。
215
+
216
+ ---
217
+
218
+ > 更新记录:[`CHANGELOG.md`](./CHANGELOG.md)
219
+
220
+ ## 许可
221
+
222
+ MIT。
package/docs/internals.md CHANGED
@@ -477,19 +477,86 @@ knownOrgs 去重)。真机:`node tests/smoke.mjs` 仍能跑通(凭据从
477
477
 
478
478
  ```
479
479
  launchLoginBrowser(url)
480
- → findBrowser() Edge / Chrome / Brave / Chromium,按平台列路径逐个 existsSync
481
- → spawn(exe, [
482
- --user-data-dir=~/.cache/magpie/magicrew-login-<pid>-<ts>-<rand>, ← 一次性,见下面 ②
483
- --remote-debugging-port=0, ← 0 = 让系统挑空闲端口
484
- --no-first-run, --no-default-browser-check,
485
- url,
486
- ])
487
- → 等 <user-data-dir>/DevToolsActivePort 出现,第一行是端口
480
+ → browserCandidates() 按优先级列出候选,逐个 existsSync 过滤出真实存在的
481
+ → 对每个候选依次 launchOne():
482
+ spawn(exe, [
483
+ --user-data-dir=~/.cache/magpie/magicrew-login-<pid>-<ts>-<rand>, ← 一次性,见下面 ②
484
+ --remote-debugging-port=0, ← 0 = 让系统挑空闲端口
485
+ --no-first-run, --no-default-browser-check,
486
+ url,
487
+ ])
488
+ 等 <user-data-dir>/DevToolsActivePort 出现,第一行是端口
489
+ ├─ 拿到端口 → 就用它,返回 { port, dir, child, name, exe }
490
+ └─ 没拿到 → 杀进程 + 删目录,换下一个候选
491
+ → 全部失败才抛错,错误里带每个候选的失败原因
488
492
  ```
489
493
 
490
494
  ⚠ 启动前**必须删掉** `DevToolsActivePort` —— 上一次残留的文件会让 `waitPort` 立刻
491
495
  返回一个已经失效的旧端口。
492
496
 
497
+ #### 浏览器优先级(0.3.15,按「谁最干净」而不是名气)
498
+
499
+ ```
500
+ ① Chrome / Chromium 自己装的,无企业策略、无强制登录、无侧边栏 ← 首选
501
+ ② 国产 Chromium 系 360 / QQ / 搜狗 / 2345 / 猎豹 / UC / 夸克 —— 用户日常在用的
502
+ ③ Edge 垫底
503
+ ```
504
+
505
+ Edge 放最后的三个理由:
506
+
507
+ 1. 企业/组策略常禁用远程调试,是所有候选里**起不来概率最高**的
508
+ 2. 会被系统账号强制接管、带侧边栏与首次运行引导
509
+ 3. 用户明确反馈不愿意用
510
+
511
+ #### ⚠ 本案根因(2026-10-28):写死单个文件名一定漏
512
+
513
+ 现象:点「浏览器登录」→ 用户在浏览器里登完了、页面跳到 agent 界面了 →
514
+ magpie 卡片一直停在「请在浏览器中完成登录」,5 分钟后超时。
515
+
516
+ 判据(每次登录都往这里写一行):
517
+
518
+ ```
519
+ ~/.cache/magpie/magicrew-login-<site>.log
520
+ [2026-10-27T16:33:25.497Z] launch: 本机没找到 Chrome / Edge / Bravo / Chromium
521
+ ```
522
+
523
+ **但这台机器上 Edge 是装着的**(`122.0.2365.106`,微软官方包)。查下来:
524
+
525
+ ```
526
+ 注册表 HKLM\...\StartMenuInternet\Microsoft Edge\shell\open\command
527
+ → "C:\Program Files (x86)\Microsoft\Edge\Application\Microsoft Edge.exe"
528
+
529
+ 实际目录里: "Microsoft Edge.exe" ← 微软落盘的名字,带空格、带大写
530
+ 代码里写死: "msedge.exe" ← 这个名字在本机**不存在**
531
+ ```
532
+
533
+ **反过来也成立** —— 另一台 Windows(Edge 156.0.4314.42)上照样跑同一份代码,
534
+ 但它 `%ProgramFiles(x86)%\Microsoft\Edge\Application\` 里只有 `msedge.exe`,
535
+ `Microsoft Edge.exe` 不存在。⇒ **两个名字都得留,谁在就用谁**;
536
+ 只留一个,就必有一类机器永远走降级。这一条 2026-10-28 在两台机器上双向验过。
537
+
538
+ `existsSync` 一路 miss → `findBrowser()` 返回 `null` → **永远**走降级路径
539
+ (系统浏览器 + 让用户去 Console 粘一行)。用户不知道有 Console 这一步,
540
+ 只会觉得「我明明登好了,插件没反应」。
541
+
542
+ ⇒ 修法两条,缺一不可:
543
+
544
+ 1. **两个名字都留着**:`Microsoft Edge.exe`(微软真实落盘)+ `msedge.exe`(有些装法是这个)
545
+ 2. **不能只挑「第一个存在的」就认定它能用** —— 存在 ≠ 能起 CDP。
546
+ 改成逐个试,第一个真写出 `DevToolsActivePort` 的才算数。
547
+
548
+ #### 实测数据(2026-10-28,本机)
549
+
550
+ | 浏览器 | 起 CDP | 页面就绪 | 读凭据 | 备注 |
551
+ |---|---|---|---|---|
552
+ | **Chromium 154.0.8037.93**(scoop) | 650–800 ms | ~2 s | ✓ | **当前选中**,端到端 3.4 s 全通 |
553
+ | Edge 122.0.2365.106 | ✓ | ~2 s | ✓ | 可用,但按上面理由垫底 |
554
+ | 360ChromeX(Chrome 132 内核) | ✓ | — | ✓ | 用户日常浏览器,CDP 正常 |
555
+ | 360se6 / 搜狗 / QQ | — | — | — | 本机装了 360se6,未逐一验证 |
556
+
557
+ 真机复跑:`node tools/verify-profile-scope.mjs`(窗口打开 4 秒后 `READ_CREDS` 必须是空串,
558
+ 关窗后目录必须不存在)。单元判据:`node tests/browser-detect.mjs`。
559
+
493
560
  ```js
494
561
  waitForCreds(session, hostFragment)
495
562
  → 每 1.5s:连 /json/list → 找 URL 含 hostFragment 的 page target
@@ -549,11 +616,16 @@ waitForCreds(..., { baseline }) → 第二道防线:窗口打开时就有的
549
616
  ### 降级链
550
617
 
551
618
  ```
552
- 找到浏览器 → 自己拉 + CDP 读 全自动
553
- 找不到 → magpie 开系统浏览器 + 剪贴板 用户粘一行
554
- 都没有 → 报错,让用户改用「登录态(JWT + 组织码)」
619
+ 候选里有一个能起 CDP → 自己拉 + CDP 读 全自动
620
+ 一个都起不来 → magpie 开系统浏览器 + 剪贴板 用户粘一行
621
+ 连浏览器都没有 → 报错,让用户改用「登录态(JWT + 组织码)」
555
622
  ```
556
623
 
624
+ ⚠ 这条链**只有第一环的判断是对的才算数**。0.3.12 及更早,第一环用的是
625
+ 「文件名写死的 `msedge.exe` 是否存在」—— 文件名错了就永远落到第二环,
626
+ 而第二环要求用户去按 F12 开 Console,绝大多数人不会做,看到的就是「一直等」。
627
+ 判据是 `~/.cache/magpie/magicrew-login-<site>.log` 里那行 `launch: ...`。
628
+
557
629
  > 0.2.0 里那条「密码登录」方法已经删掉了:网页登录拿到的 token 一样能签发
558
630
  > `mgw_` key(见第十节的更正),再让用户在小窗里输手机号密码是多余的一步。
559
631
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magicrew-auth",
3
- "version": "0.3.14",
3
+ "version": "0.3.15",
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",