magicrew-auth 0.3.13 → 0.3.14
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 +58 -0
- package/README.md +208 -208
- package/docs/internals.md +3 -1
- package/package.json +1 -1
- package/src/api.mjs +25 -0
- package/src/browser-login.mjs +408 -408
- package/src/clipboard.mjs +106 -106
- package/src/hooks/loader.mjs +93 -93
- package/src/hooks/models.mjs +17 -6
- package/src/icons.mjs +24 -24
- package/src/model-context.mjs +100 -100
- package/src/tasks.mjs +22 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
# 更新记录
|
|
2
2
|
|
|
3
|
+
## 0.3.14
|
|
4
|
+
|
|
5
|
+
**两处判据修正:国际站看「话题」而不是「项目」;「免费」不再从倍率反推**
|
|
6
|
+
|
|
7
|
+
来自 PR #4(`fix/free-rate-and-topic-guard`,白九)。两点判断都对,都收;
|
|
8
|
+
落地时各改了一处。
|
|
9
|
+
|
|
10
|
+
### 一、国际站首对话:判据从「有没有项目」换成「有没有话题」
|
|
11
|
+
|
|
12
|
+
上一版把「已有工作台项目」当成「发过消息」。**这个前提不成立** —— 项目在打开
|
|
13
|
+
工作台时就会自动建,「建了项目、一句话没说」的新号很常见,而那种号正是要补的。
|
|
14
|
+
被误判成「用过」之后还会落一次性标记,等于永久跳过。
|
|
15
|
+
|
|
16
|
+
改成:拿项目 → 列它的话题 → 有话题才跳过,没话题就补一条。
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
GET /api/v1/super-agent/projects/{id}/topics
|
|
20
|
+
→ { code:1000, data:{ total, list:[{ id, chat_topic_id, chat_conversation_id, topic_name, task_status, … }] } }
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### 二、`free` 改成三分支(按 `HOOKS.md` 十一之二)
|
|
24
|
+
|
|
25
|
+
`free` 的判据是「花不花这份订阅的额度」,**不能从 `rate` 反推**。原来的二元
|
|
26
|
+
判断把「价格为 0」和「价格未知」混在一起,两种情况都变成 `rate: 0`:
|
|
27
|
+
|
|
28
|
+
| `input_points` | 处理 |
|
|
29
|
+
|---|---|
|
|
30
|
+
| > 0 | `rate = n / 2000`,不设 `free` |
|
|
31
|
+
| === 0 | `free: true`,不给 `rate`(厂商声明免费 → 进 Free first 那一档) |
|
|
32
|
+
| 缺失 | **不列** —— 不猜价格,也不谎标免费 |
|
|
33
|
+
|
|
34
|
+
产出走 `modelEntry` 已有的 `free` / `rate` 出口(`src/context.mjs` 里
|
|
35
|
+
`free` 为真时不输出 `rate`,两者不会同时出现)。
|
|
36
|
+
|
|
37
|
+
### 与原 PR 的两处不同
|
|
38
|
+
|
|
39
|
+
1. **查不到 ≠ 没说过话。** 原版 `fetchProjectTopics(...).catch(() => [])`,
|
|
40
|
+
接口抖一下就当成「没有话题」,于是白花一次积分去补消息。改成:查不到就
|
|
41
|
+
**这次不发**、不落标记、不计失败次数,留到下次登录 / 签到再查。
|
|
42
|
+
失败方向要选「宁可漏一轮」那一侧 —— 消息发出去是花钱且不可撤的。
|
|
43
|
+
2. **`Number("") === 0` 会误判免费。** 原版用 `p.inputPoints != null` 判「已知」,
|
|
44
|
+
空串也会通过并被算成 0 点。现在要求非空且是有限数字,才算已知价格。
|
|
45
|
+
|
|
46
|
+
### 实测(2026-10-28,两站真接口)
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
magicrew org=66p0q56qo47j workspace 801580653401091055 projects 1 topics 2 ✓
|
|
50
|
+
magicrew-intl org=67u4oe6fbenj workspace 801566935627653258 projects 1 topics 1 ✓
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
两站同一个 workspace 下 `GET /projects/{id}/topics` 都是 `code:1000`、
|
|
54
|
+
`data.list[]` 字段名逐字一致(`chat_topic_id` / `chat_conversation_id` /
|
|
55
|
+
`topic_name` / `task_status`),与国内站的 chat-task 链路同构。
|
|
56
|
+
|
|
57
|
+
⚠ 当前两个账号的模型表里 **76 条模型的 `input_points` 全部 > 0,没有一条 0**
|
|
58
|
+
(国内 27 + 国际 49,实测快照)—— 所以三分支这批改动眼下不改变任何列表内容,
|
|
59
|
+
它防的是「以后出现真免费的模型」。这一条未能在本机实测覆盖。
|
|
60
|
+
|
|
3
61
|
## 0.3.13
|
|
4
62
|
|
|
5
63
|
**首任务补完:登录那一刻做一次,之后永不再发(补齐 0.3.12 的另一半)**
|
package/README.md
CHANGED
|
@@ -1,208 +1,208 @@
|
|
|
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 / 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。
|
package/docs/internals.md
CHANGED
|
@@ -702,7 +702,7 @@ mgw_8f9a…(18:14 又一次续期换的) → 网关请求 HTTP 200 正
|
|
|
702
702
|
① POST /api/v1/login-gift 领每日登录积分(国内 +200、国际 +50;当天已领回 granted:false,幂等)
|
|
703
703
|
② 首任务 / 首对话没做过 → 走 Socket.IO 发一条消息(纯 Node,不开浏览器)
|
|
704
704
|
国内站:onboarding 的 first_ai_work 还是 PENDING → 建话题 + 发一条,轮询等 COMPLETED
|
|
705
|
-
国际站:onboarding 恒返回空任务 →
|
|
705
|
+
国际站:onboarding 恒返回空任务 → 改看「有没有话题」,一个话题都没有才发
|
|
706
706
|
③ 其余新手福利 → PUT /api/v1/onboarding/tasks/<code>/completion
|
|
707
707
|
④ 报积分变化
|
|
708
708
|
```
|
|
@@ -730,6 +730,8 @@ mgw_8f9a…(18:14 又一次续期换的) → 网关请求 HTTP 200 正
|
|
|
730
730
|
| 真去发了但失败 | `status: "failed"`,`attempts++` | 发,最多 3 次 |
|
|
731
731
|
| 连失败 3 次 | `status: "gave-up"` | 不发(别让永远失败的号每次撞一遍) |
|
|
732
732
|
| 还没有工作台 / 项目 | 不写 | 发,下次再来(只读接口,成本低) |
|
|
733
|
+
| 有项目、但话题一个都没有 | 不写 | **发**(项目是打开工作台时自动建的,不代表说过话) |
|
|
734
|
+
| 话题清单查不到(接口失败) | 不写 | **这次不发**,下次再来(不把「查不到」当「没说过话」白花积分) |
|
|
733
735
|
| 服务端本来就是 COMPLETED | `status: "sent"` + `reason` | 不发 |
|
|
734
736
|
|
|
735
737
|
老版本(0.3.11)记的是 `{ [org]: "YYYY-MM-DD" }` 字符串日期 —— 读的时候按「已发过」
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "magicrew-auth",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.14",
|
|
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",
|
package/src/api.mjs
CHANGED
|
@@ -476,6 +476,31 @@ export async function fetchFirstWorkspaceId(token, org, host = SITES.cn.host) {
|
|
|
476
476
|
return String(w?.id ?? w?.workspace_id ?? w?.workspaceId ?? "")
|
|
477
477
|
}
|
|
478
478
|
|
|
479
|
+
// ── ④e 某个项目下的话题 ──────────────────────────────────────────────
|
|
480
|
+
//
|
|
481
|
+
// GET /api/v1/super-agent/projects/{id}/topics
|
|
482
|
+
// → { total, list:[{ id, chat_topic_id, chat_conversation_id, topic_name, task_status, … }] }
|
|
483
|
+
//
|
|
484
|
+
// 判断「这个账号到底发没发过消息」看的是它,**不是「有没有项目」** ——
|
|
485
|
+
// 项目在打开工作台时就会自动建,「有项目、没话题」的新号很常见。
|
|
486
|
+
// 实测(2026-10-28):国内站 magicrew / 国际站 magicrew-intl 两站同构,
|
|
487
|
+
// 同一个 workspace 下都返回 { code:1000, data:{ total, list } }。
|
|
488
|
+
export async function fetchProjectTopics(token, org, projectId, host = SITES.cn.host) {
|
|
489
|
+
const res = await fetch(`${host}/api/v1/super-agent/projects/${projectId}/topics`, {
|
|
490
|
+
headers: headersFor(token, org, host),
|
|
491
|
+
})
|
|
492
|
+
const body = await read(res)
|
|
493
|
+
const d = body?.data ?? {}
|
|
494
|
+
const list = Array.isArray(d.list) ? d.list : []
|
|
495
|
+
return list.map((t) => ({
|
|
496
|
+
id: String(t.id ?? ""),
|
|
497
|
+
chatTopicId: String(t.chat_topic_id ?? ""),
|
|
498
|
+
chatConversationId: String(t.chat_conversation_id ?? ""),
|
|
499
|
+
name: String(t.topic_name ?? ""),
|
|
500
|
+
status: String(t.task_status ?? ""),
|
|
501
|
+
}))
|
|
502
|
+
}
|
|
503
|
+
|
|
479
504
|
// ── ④c 这个登录态是谁 ────────────────────────────────────────────────
|
|
480
505
|
//
|
|
481
506
|
// 卡片上原来显示组织码(orgcode67890 / orgcode12345),那是随机串,用户认不出是谁。
|