Repository navigation
Releases
v0.3.0 · 界面照原站重做(日志/密钥/推荐计划)+ ?demo 预览
0.3.0
界面照原站重做,并加了一层可离线预览的虚拟数据。
- 使用日志:筛选(日/周/月 + 模型/分组/类型/令牌名/请求 ID)、用量·请求·Token 统计条与隐私遮罩、9 列明细(吞吐、Token/缓存、首字·耗时)、分页与载入更多。
- API 密钥:原站的标题行 + 筛选行 + 表格(9 列);新建改居中弹窗,样式与模型详情面板统一。修 .modal-backdrop 压过 hidden 导致弹窗关不掉的缺陷。
- 推荐计划:待确认 / 总收入 / 邀请三列 + 链接胶囊 + 复制图标 + 转移到余额,位置在 API 密钥卡上方。
- ?demo:拦截全部 GET 返回虚拟数据,写请求放行,可离线看四页完整形态。
- 整页限高:页头、标签、页脚固定,超长内容下放到各卡片内部滚动。
- 图标与包名:主图标换 Ciallo 立绘,标签页加星标,可见名称统一为 @fish-under-sea/magpie-dragonapi。
安装:下载 ish-under-sea-magpie-dragonapi-0.3.0.tgz,解包成目录后 magpie plugin add <那个目录>。
v0.2.1 · 版本号跟进(代码同 0.2.0)
0.2.1
代码与 0.2.0 完全相同,只有版本号不同。这个版本存在的原因是 npm 的暂存发布窗口:
0.2.0补发时,npm publish立刻返回成功,但版本要等几分钟到十几分钟才在 registry 上转正(暂存发布:bypass-2FA 的 granular token 在 2026-07-31 之后只能 staged publish,需维护者 2FA 批准)。- 窗口期内重发会撞
E409 Cannot publish over previously staged version,看起来像「发布失败」,其实第一次已经成功。 - 为确认「换个版本号能否绕过窗口」,又发了
0.2.1,同样转正。
现在 0.2.0 与 0.2.1 都在 npm 上,latest 指向 0.2.1,与仓库、tag 对齐。
安装用 latest 即可,两者没区别:
magpie plugin add @fish-under-sea/magpie-dragonapi发版提示:以后发布后不要立刻用
npm view <pkg> version判断成败——暂存窗口内它仍然显示旧版本。以npm view <pkg>@<version>返回 200 为准,或直接等 10 分钟再查。
v0.2.0 · 补发:修 PAT 保存与插件加载,重绘界面
0.2.0
补齐发布:npm 上此前只有 0.1.5,0.2.0 打了 tag 却没发。这一版把 repo、tag、release、npm 对齐到同一份代码。
修的两个真问题
- 访问令牌保存失败:
setPat链路上的问题,导致填了 PAT 也读不到账户与钥匙。 - 插件加载失败 / 供应商不注册:入口里多余的命名导出让宿主把模块当成别的东西,插件行报「没有加载成功」,供应商也不出现。
界面重绘(含近场 UI 分支合并,PR #1)
- 模型广场:侧栏按厂商分类(Claude / GPT / Gemini / Grok / 国模 / Image / Video,分组 chip 前置等宽倍率标签);顶部工具条横跨整页,含
/1M–/1K单位切换、自绘排序菜单、双列 / 列表切换;列表视图是七列表格;端点显示 Chat / Response / Anthropic 这类可读名;站点没写说明的模型按目录字段自动补一句。 - 余额页:改为账户概览(大字金额 + 已用 / 分组 / 钥匙尾号 / 模型数 / 绑定时间)与数据概览(消耗 / 当前余额 / Token + 按时段柱状条 + 按模型明细)。
- 底层:
priceOf同时给出每百万 token 的数值,供单位切换与按价格排序;/api/model额外返回同型号各分组的定价(详情页「按分组定价」)。
本地实时预览
node dev.mjs 起一个预览服务,改 ui/ 里任何文件都自动整页刷新,不需要装 magpie。
/__sandbox 模式套与 magpie 相同的 sandbox="allow-scripts" iframe,用来提前发现「不透明源」相关问题(此前造成过「装进 magpie 后所有接口都连不上」)。
测试
163 个用例通过。
说明:
v0.2.0tag 已对齐到本次发布的提交,使 tag / release / npm 三者指向同一份代码。
v0.1.5 · 四页统一页面层级
把四个页面统一成一套层级
上一版只重做了模型广场,其余三页仍是「直接铺一堆卡片」,所以整体看起来像局部改过。这一版把层级补齐。
每个标签页现在都有页面级标题 + 一句话说明,卡片标题降到 h3:
h1 DragonAPI(应用名)
h2 模型广场 / 余额与用量 / 密钥 / 访问令牌(页面)
h3 账户余额 / 用量汇总 / 新建密钥 / 需要哪些权限 …(卡片)
h4 分组(侧栏小节)
此前是从 h1 直接跳到卡片 h2,标签名和卡片名还会重复(标签「访问令牌」下的第一张卡也叫「访问令牌 PAT」)。现在标签是导航、页头是身份、卡片标题是分区。
修了两处具体缺陷
- 账户卡把打码钥匙显示了两次:服务端给的 label 本身就是「分组 · 打码钥匙」,页面又单列了一次
masked。现在 label 里已含就不重复显示。 - 余额显示「—」却没有解释:那不是没钱,而是插件进程还没拿到这把钥匙的明文(冷启动后要等宿主调一次
models/usage才会填)。现在鼠标悬停会说明该怎么办。
验证
- 133 个单测通过,新增 2 条:四页各有
page-head且卡片标题必须是 h3、账户卡不得重复打码。 - 深色四页全部重拍核对;窄屏此前已确认无横向溢出。
v0.1.4 · 卡片网格改版 + 修复加载超时
这次修了一个让插件「加载失败」的 bug
装好后 Settings → Plugins 里可能显示 没有加载成功:the plugin's load didn't finish in 20s。
根因:插件入口在加载时 await 了站点请求,而宿主的插件加载有 20 秒上限,网络一慢就把加载拖死。本地服务其实已经起来了、页面也能开,所以这个提示和「页面能打开」的现象很容易看反。现在改成后台预热、绝不等待(实测 3.7ms 返回)。
卡片不再参差
并排卡片不等高,是因为网格上写了 align-items: start。现已改成 stretch,并让卡内纵向 flex、页脚 margin-top: auto 吸底。三处必须同时到位,少一处还会参差。
模型广场改为卡片网格
按 NearToken 的信息结构重做:
- 布局:左侧 208px 筛选栏(14 个分组,带倍率与模型数)+ 右侧双列卡片网格;窄屏单列、分组变横向滚动条。
- 卡片:名称/厂商 → 说明 → 计费方式(倍率/分档/按次/按秒)→ 输入·输出·缓存 三列等宽数字 → 分组倍率 → 端点 → 详情。
- 类型筛选从下拉改成 chip 并移到主区顶部,桌面不再被侧栏裁掉。
两处刻意没照搬,因为照抄就得造假:
| NearToken 有 | 我们的处理 | 原因 |
|---|---|---|
| 每张卡的「已启用/未启用」开关 | 不做,纯展示 | 本站做不到按模型启停;按你之前的要求不给假开关 |
| 实时健康度(延迟、吞吐、成功率条) | 不做,位置换成上下文与计费档位 | 我们没有这项数据,编出来比留白更糟 |
有测试禁止卡片里出现「延迟/吞吐/成功率」这类词,防止以后有人顺手补上假数据。
顺带修的可访问性与体感
- 首次打开(还没设 PAT)不再甩红色错误横幅,改成引导式空态 +「去设置访问令牌」按钮——未配置不是错误。
- 表单控件改用 padding 撑高(34px);移动端字号提到 16px,避免 iOS 聚焦时自动放大整页。
.link命中区补到 24px、窄屏 32px(WCAG 2.2 AA);按钮与卡片加touch-action: manipulation;body补100dvh回退;抽屉加overscroll-behavior: contain。
验证
- 131 个单测通过,新增 6 条:等高结构三要素、卡片信息位齐全、禁止伪造健康度、未配置引导、插件加载不等网络。
- 视觉核对:深色/浅色桌面 + 420px 窄屏,均无横向溢出(
scrollWidth == clientWidth)。 - 说明:
ui/index.html的 516 行改动基本是行尾归一(CRLF → LF),真实改动只有市场区那几十行;另加.gitattributes防止再犯。
v0.1.3 · 修复装进 magpie 后接口全失败
修复:装进 magpie 后所有接口都「连不上本地服务」
症状:插件装进 magpie 后界面能打开,但每个接口都报「连不上本地服务,插件可能已经退出,或端口被改了」,模型广场、余额、密钥全部不可用。而直接访问 http://127.0.0.1:<端口>/ 却完全正常。
根因:magpie 的插件页跑在 sandbox="allow-scripts" 的 iframe 里,安全源是不透明的(self.origin === "null",localStorage / cookie 都抛 SecurityError)。在这种文档里相对路径的 fetch('/api/ping') 会被 Chrome 判 TypeError: Failed to fetch,绝对地址却正常。实测:
| 调用 | 结果 |
|---|---|
fetch('/api/ping') |
❌ TypeError: Failed to fetch |
fetch('http://127.0.0.1:3671/api/ping') |
✅ 200 |
界面此前全用相对路径,于是全挂。
修复:
ui/app.js新增API_BASE:从location.href推导绝对基址,所有请求经apiUrl()拼成绝对地址(用href而非origin,因为不透明文档里location.origin不可靠)。基址保留 pathname 目录,所以 magpie web 的_magpie/service/<token>/代理前缀不会丢。page/boot.js:跳转前保证服务地址以/结尾,否则代理路径里的 token 会被当成文件名丢掉。lib/service.mjs:/api/ping的版本改从package.json读,不再硬编码(之前一直报 0.1.0,排查时容易误判)。- 补上
Access-Control-Allow-Private-Network: true(不透明源访问 loopback 的预检要求),CORS 头收敛到一处。
验证:在 sandbox="allow-scripts" 的 iframe 里真实等待后确认——已连接、186 行模型、价格正常、健康记录正常。125 个单测通过,含新增的静态回归断言(fetch 必须经 apiUrl、不许出现 fetch('/api…')、boot.js 必须处理结尾斜杠、ping 版本须与 package.json 一致)。
排查提示:
--virtual-time-budget截图会在真实网络返回前就拍,拍出假的「加载中」,别用它判断这类问题。
v0.1.2 · 安装说明与卡片元数据
首个可用版本。
形态
magpie 的供应商插件 + 页面插件,独立 npm 单包,不依赖 FISH Dock。
站点侧的两条硬约束决定了形态:
https://newapi.dragon3api.com/没有设备授权端点,登录要过人机校验,PAT 只能浏览器里建;- 分组是钥匙的属性(
TokenAuth里userGroup = tokenGroup),请求头没有任何入口能改它 ——
所以 NearToken 那种「按组切换」在这里做不到。
于是分组即账号:一个分组一把钥匙,模型 id 用 分组/模型,每个账号的 models 清单只列它那一组,
由宿主把这些请求送到对的账号。
组成
| 模块 | 作用 |
|---|---|
index.mjs |
config / auth / provider.models,并起本地服务 |
lib/site.mjs |
sk- 与 PAT 两条通道严格分开 |
lib/pricing.mjs |
倍率计费 + 表达式计费,算不准就明说未知 |
lib/catalog.mjs |
/api/pricing → 195 行「分组×模型」 |
lib/catalog-source.mjs |
目录的唯一所有者:缓存、304、刷新、降级 |
lib/status-source.mjs |
站点参数的唯一所有者 |
lib/service.mjs |
本地 HTTP 服务(页面沙箱发不出请求,只能导航过来) |
lib/usage.mjs |
日志解析、汇总、窗口 |
lib/store.mjs |
本地状态,原子写 0600,不存钥匙明文 |
page/ + ui/ |
带路页 + 四标签界面 |
界面
- 模型广场:122 模型 / 195 行 / 14 分组,可筛选搜索。纯展示,没有启用停用开关(本站做不到按组启停,不给假开关)。
- 余额与用量:多账号余额、按天周月汇总、逐条流水。
- 密钥:按分组建新钥匙、显示一次明文、复制、删除、查看完整钥匙。
- 访问令牌:填入清除 PAT,说明所需 scope。
验证
- 122 个单元测试
- 24 项真实站点检查(122 模型 / 195 行 / 14 分组 / 价格可算 100% / 304 条件请求生效)
- 深色、浅色、移动端三种视口视觉核对
本版变化(0.1.2)
- 补 magpie.name / magpie.summary:Discover 卡片与 Settings 里的插件行有了名字和描述
- README 补「安装」一节:Discover / 命令行 / 离线 tgz 三条路
- 0.1.1 与 0.1.2 行为一致,仅元数据与文档变化
已知限制
- 页面跑在沙箱里,写不了 magpie 的账号表,所以绑定只能走 magpie 自己的「添加账号」;
插件用第二条登录方式(用访问令牌按分组自动建钥匙)把「建钥匙 + 绑定」合成一步。 - 视频按秒计费只能给区间价。
- 站点前端的
priceRate(充值价系数)未能验证;只影响单价显示,不影响流水里的实际费用。
v0.1.0 · 首个可用版本
首个可用版本。
形态
magpie 的供应商插件 + 页面插件,独立 npm 单包,不依赖 FISH Dock。
站点侧的两条硬约束决定了形态:
https://newapi.dragon3api.com/没有设备授权端点,登录要过人机校验,PAT 只能浏览器里建;- 分组是钥匙的属性(
TokenAuth里userGroup = tokenGroup),请求头没有任何入口能改它 ——
所以 NearToken 那种「按组切换」在这里做不到。
于是分组即账号:一个分组一把钥匙,模型 id 用 分组/模型,每个账号的 models 清单只列它那一组,
由宿主把这些请求送到对的账号。
组成
| 模块 | 作用 |
|---|---|
index.mjs |
config / auth / provider.models,并起本地服务 |
lib/site.mjs |
sk- 与 PAT 两条通道严格分开 |
lib/pricing.mjs |
倍率计费 + 表达式计费,算不准就明说未知 |
lib/catalog.mjs |
/api/pricing → 195 行「分组×模型」 |
lib/catalog-source.mjs |
目录的唯一所有者:缓存、304、刷新、降级 |
lib/status-source.mjs |
站点参数的唯一所有者 |
lib/service.mjs |
本地 HTTP 服务(页面沙箱发不出请求,只能导航过来) |
lib/usage.mjs |
日志解析、汇总、窗口 |
lib/store.mjs |
本地状态,原子写 0600,不存钥匙明文 |
page/ + ui/ |
带路页 + 四标签界面 |
界面
- 模型广场:122 模型 / 195 行 / 14 分组,可筛选搜索。纯展示,没有启用停用开关(本站做不到按组启停,不给假开关)。
- 余额与用量:多账号余额、按天周月汇总、逐条流水。
- 密钥:按分组建新钥匙、显示一次明文、复制、删除、查看完整钥匙。
- 访问令牌:填入清除 PAT,说明所需 scope。
验证
- 122 个单元测试
- 24 项真实站点检查(122 模型 / 195 行 / 14 分组 / 价格可算 100% / 304 条件请求生效)
- 深色、浅色、移动端三种视口视觉核对
已知限制
- 页面跑在沙箱里,写不了 magpie 的账号表,所以绑定只能走 magpie 自己的「添加账号」;
插件用第二条登录方式(用访问令牌按分组自动建钥匙)把「建钥匙 + 绑定」合成一步。 - 视频按秒计费只能给区间价。
- 站点前端的
priceRate(充值价系数)未能验证;只影响单价显示,不影响流水里的实际费用。