npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mangoc/dsh-sub2api-sync

v0.2.8

Published

Sync one sub2api instance's groups, keys, and models into dsh-llm-pi-ai provider routes: panel-driven login (password / OAuth), one relay key one provider.

Readme

@mangoc/dsh-sub2api-sync

把一个 sub2api 实例的分组、密钥、模型同步为 dsh-llm-pi-ai 的 provider 路由:登录一次、自动集成、持续同步。

设计 Agent Note:Phase 1 设计 与 客户端 UI 改造(当前实现基准)。

状态:Mode A(面板驱动)+ 客户端 UI

  • 登录通道:面板密码+2FA(C3)已交付;网页授权(C2,OAuth 授权码 + PKCE)待 sub2api 侧部署后接入。PAT(C1)已随本插件移除——sub2api 上游从未部署对应端点,该通道无令牌来源;
  • Keys 驱动同步:Keys 卡列出面板已有 relay key(缺省全不选)→ 勾选多把(可跨分组)→「同步所选」→ 一把 key 一个供应商(路由 sub2api-<10-hex>,不含顺序 id)→ 模型下一请求即可用;需要新 key 用「创建 key」弹窗(默认与分组同名);
  • 供应商命名:providerNameTemplate 渲染,缺省 {siteName}({keyName})——即 <站点名称>(<key 名>),站点名称来自实例探测;
  • UI:设置页顶级卡片(settings.section)+ 插件页调参卡(plugins.bundle.config),样式对齐 ui-settings-account,文案全双语(zh/en);
  • 数据缝:配置读写走平台 configForms(字段级、revision 围栏、schema 校验);宿主路由只承载动作/秘密/状态投影;
  • 指纹路由(旧 Mode B)与分组驱动同步(rev.5)均已退役——同步锚定真实面板 key id。

安装

用户安装(发布渠道)

harness 通过包的 main/exports 入口加载插件,即构建产物 lib/index.js。以下任一渠道装到的 tarball 都自带 lib/,无需本地构建:

npm——两个包名同步发布:同一份代码、同一版本号,scoped 为 canonical,无 scope 短名为别名,任选其一安装:

dsh plugin --profile web add @mangoc/dsh-sub2api-sync   # canonical(scoped)
dsh plugin --profile web add dsh-sub2api-sync           # 别名(无 scope 短名)

GitHub Releases tarball(不依赖 npm;地址始终指向最新版):

dsh plugin --profile web add https://github.com/Shuai-S/dsh-sub2api-sync/releases/latest/download/dsh-sub2api-sync.tgz

从源码安装(pnpm 会对 git 依赖自动执行 prepare 构建;需要本机构建链,首次较慢):

dsh plugin --profile web add github:Shuai-S/dsh-sub2api-sync#path:packages/llm/sub2api-sync

装好后重启应用、或在插件页把开关关掉再打开,让入口重新 import 一次;失败的条目不会自动重试。

发布(维护者)

每次发版双包同步发布(scripts/pack-all.mjs):scoped canonical 与无 scope 别名各出一个 tarball,版本号完全一致;客户端 bundle 内嵌的插件名(挂载 key、详情页匹配、ModuleLoader id)与 cordis.patch.yml 在打包时按包名注入,两个变体都可独立安装。CI(.github/workflows/release.yml)自动完成全流程:bump packages/llm/sub2api-sync/package.json 的 version → 提交 → git tag vX.Y.Z && git push origin vX.Y.Z → pnpm check → 双 tarball → npm 双发布(需要仓库 secret NPM_TOKEN;publishConfig.registry 已锁定 npmjs 官方源,不受 npmmirror 镜像影响);GitHub Release 附短名 tarball 资产。本地手动双发布:

pnpm pack:all    # 产出 dist/ 下两个 tarball,仓库文件自动还原
npm publish dist/mangoc-dsh-sub2api-sync-*.tgz --registry=https://registry.npmjs.org --access public
npm publish dist/dsh-sub2api-sync-*.tgz --registry=https://registry.npmjs.org --access public

只发 canonical 亦可:pnpm --filter @mangoc/dsh-sub2api-sync publish。

本地开发(link 调试)

dsh plugin add 对本地目录只做软链(link:),不会为目标目录安装依赖或执行构建,所以先构建是硬性前置条件,而不是「开发时的可选步骤」:

pnpm install          # 安装依赖(会触发 prepare 构建)
pnpm build            # tsdown + 客户端包装;产出 lib/index.js 与 lib/client.js
dsh plugin --profile web add ./packages/llm/sub2api-sync

重新构建后需要重启应用、或在插件页把开关关掉再打开,让入口重新 import 一次;失败的条目不会自动重试。

使用

  1. 点「登录」,在弹窗里填实例地址(如 https://cn.api.nexarelay.com,可带 /v1)+ 凭据(面板邮箱/密码,TOTP 账号按提示输入一次性验证码;密码会存入凭据存储,之后免输入);
  2. Keys 卡列出该实例已有的 relay key(最新创建在前,首屏 5 条,底部「加载更多」翻页)。每一行前面的勾选框 = 选中用于同步;右上角「创建 key」弹窗可新建:选分组 → 名称默认与分组同名 → 创建即自动勾选;
  3. 勾选好要用的 key(可多选、可跨分组),点「同步所选(N)」——引擎为每一把勾选的 key 建一个供应商,各自发现模型、按所属分组平台映射协议(anthropic → anthropic-messages,OpenAI 家族 → openai-responses,其余 → openai-completions,可按分组覆盖),写入 llm-pi-ai.providers;
  4. 模型选择器下一请求即可用。主卡下方的「同步」块也能触发一次全量同步并查看完整报告;报告的每个条目带「移除」按钮——只删本地路由与凭据(不调面板,余额不足也可用),并自动取消该 key 的勾选,下次同步不会复活;可选高级参数在 插件页 → Sub2API Sync 调参卡。

安全

  • 一切秘密(面板 token、密码、各 relay key)只进 harness 凭据存储(确定性引用 DSH_SUB2API_TOKEN_<实例哈希>、DSH_SUB2API_KEY_<key-id>、DSH_SUB2API_PASSWORD_<实例哈希>),不进 settings、不进日志、不进会话;
  • GET /keys 只回 key 元数据(id/名称/分组/状态),不回明文;明文只用于引擎解析该 key 并即时写入凭据存储;
  • 宿主动作路由只接受回环同源请求;跨设备访问 web UI 时配置只读(平台 memory 模式),动作需在 cordis.yml 显式开启 allowRemoteActions(默认关闭)。

同步做什么

对每一把勾选的 key,引擎(幂等 diff + 单飞 + 乐观并发):

  1. 取该 key 的明文(面板列表返回则用之,否则回退凭据存储:先读新式 DSH_SUB2API_KEY_<10-hex> 引用,再读旧式 DSH_SUB2API_KEY_<key-id> 迁移存底,最后尝试 OAuth reveal 接口),并保持凭据与面板一致;
  2. 携该 key 调 GET {instance}/v1/models(失败回退 modelListOverrides);
  3. 按其所属分组的 platform 映射 wire 协议并推导条目 baseURL(Anthropic SDK 给裸 host,OpenAI 系给 /v1 根);
  4. 经携带 expectedRevision 的定点 settings.mutate 写入 providers.sub2api-<10-hex>,附宽松重试策略(5 次 / 120s 退避上限)。

路由后缀是 SHA-256(实例地址, key id) 的 10 位十六进制截断——稳定、跨实例不碰撞,且刻意不含面板的顺序 key id:路由名不暴露站点发过多少 key,截图分享配置也不会泄露。条目只覆盖 sub2api-<10-hex>(现行)与 sub2api-<纯数字>(旧版遗留,下次同步自动迁移清理)两种形态(一把 key 一个供应商,显示名由 providerNameTemplate 渲染 key 名)。从勾选集消失的 key 会连带移除条目与凭据;远端 key 仅在 deleteOrphanKeys 开启时撤销(key id 由面板 key 列表反查,旧数字路由直接自带)。登出、授权失效与切换实例会整站清除本插件的同步状态——owned 路由、relay key 凭据与上次同步的报告一并清除(报告描述的状态已不存在,不得继续展示)。

Model Experience

  • 每分组一个 provider、一把 relay key;模型目录来自实例发现;逐模型 compat 继承用户模板;推理档位 reasoningEfforts 模板显式设置优先,未设置时按模型自动填充(见下);
  • 模型元数据补全(C4):同步时按模型 id 从 models.dev 目录补全显示名称(name,即模型目录编辑器「显示名称」列)/contextWindow/maxTokens/图片输入/推理档位——enrichModelMeta 开启(缺省)时联网拉取(24h 进程内缓存),失败自动降级到随包内置快照(data/models-dev.snapshot.json,pnpm --filter @mangoc/dsh-sub2api-sync models:refresh 重新生成);关闭则只用内置快照(离线确定);两者都未命中的模型保持路由级缺省 128000/8192/纯文本;
  • 推理档位自动填充:取 models.dev 条目的 reasoning_options 中 effort 枚举,映射为 pi-ai 的 reasoningEfforts(none → off: null,其余同名直传)。合并按 first-party 优先:官方厂商条目(openai/anthropic/google/zhipuai/zai/deepseek/moonshotai/xai/alibaba 等及官方云托管)存在即胜出——官方条目无 effort 数据(如旧版 Claude/Gemini 的 budget-only 条目)同样压制聚合商的虚报词表;无官方条目时聚合商来源取交集。优先级:模板显式设置(含 false)> 每模型自动填充 > 不写字段;显示名 = providerNameTemplate 渲染的 key 名。
  • Claude 原生推理档位:对已确认支持 adaptive thinking、且目录有 effort 元数据的 Claude 模型(如 Opus 4.6/4.7/4.8、Sonnet 4.6),仅在 anthropic-messages 协议下逐模型自动补齐 compat.forceAdaptiveThinking: true。该开关让 SDK 直接发送 Claude 原生的 thinking: { type: "adaptive" } 与 output_config: { effort: "max" }(以选择 Max 为例),不经过 OpenAI 协议转换,也不将 Max 降成 token budget。用户模板中同名 compat 字段(包括显式 false)优先;关闭 reasoning、旧模型、未知别名/新版本、缺少目录 effort 元数据或其他协议都不会自动开启。更新插件并重新同步即可修复已有受管路由,重复同步不重复写入;无需修改 sub2api 的记录值。注意:用量日志的 effort 是请求声明档位,不是实际思考量的测量值。
  • 显示名称富化:取 models.dev 条目的 name 写入 pi-ai 模型条目的 name 字段(模型选择器与「已自定义模型目录」编辑器的显示名);剥离 models.dev 的 " (latest)" 家族标记,名称与模型 id 相同(无信息量)时不写;合并同样 first-party 优先(官方名称覆盖,聚合商名称仅补缺),纯名称条目也参与富化。

Known Limitations and Deferred Work

  • 面板掩码明文:若你的面板账号看不到 key 明文(非管理员),同步会失败并提示用管理员账号登录——这是刻意的不静默降级。
  • 无 invariant 面:本包不发布 ./invariant(同步是一次 settings 写入,可从同一服务读回验证)。
  • 网页授权(C2)待 sub2api 侧 OAuth 端点部署(改造说明见设计 Note §12);部署前 UI 自动隐藏该通道。
  • dsh 版本下限:0.2.0-rc.2(客户端半部依赖 configForms/locale 服务;0.1.x 代 app 会响亮失败)。
  • 客户端半部只允许基线外部模块(React / Cordis / ui-primitives / ui-slots / client-store / ui-dockkit)——客户端代码不得值导入 config.ts(会把 schemastery 拽进浏览器 bundle,动态模块表无此行,加载即静默失败);test/client-bundle.test.ts 是产物守卫。
  • 实例前置 Cloudflare 时,需在 zone 放行 /api/v1/* 的宿主侧调用(WAF skip 规则)。
  • 元数据补全会向 models.dev 发起一次公开目录请求(不带任何凭据与对话内容);enrichModelMeta: false 可完全离线(仅内置快照)。
  • 推理档位自动填充只覆盖 models.dev 提供 effort 枚举的模型(OpenAI gpt-5 系/o3、GLM 5.x、Qwen3.8、DeepSeek V4 系等);toggle/budget_tokens 型推理(旧版 Claude、Gemini、deepseek-v3.2、kimi-k2.x 等)的线上形态不是 effort 字符串,reasoningEfforts 无法表达,仍由模板/compat 管辖。
  • 用量查询(GET /v1/usage)是已决策的非目标。
  • 与社区插件 GodD6366/dsh-sub2api 同装:路由名不冲突(本插件 sub2api-<10-hex> 摘要形态),各自管理条目与凭据引用。

开发

pnpm install
pnpm --filter @mangoc/dsh-sub2api-sync typecheck
pnpm --filter @mangoc/dsh-sub2api-sync test
pnpm --filter @mangoc/dsh-sub2api-sync build

MIT