creditdaddy 1.5.2 → 1.6.2

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/build.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
- "version": "1.5.2",
3
- "commit": "104e14f",
2
+ "version": "1.6.2",
3
+ "commit": "79b48f0",
4
4
  "branch": "main",
5
- "builtAt": "2026-10-18T08:14:40.111Z",
5
+ "builtAt": "2026-10-28T00:45:02.695Z",
6
6
  "channel": "local",
7
7
  "dirty": false
8
8
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "creditdaddy",
3
- "version": "1.5.2",
3
+ "version": "1.6.2",
4
4
  "description": "CreditDaddy — Qoder / WorkBuddy / ZCode / mirasim / 妙手 / Trae / MiniMax / ModelScope 多账号本地管理与每日积分自动签到助手,及 10Router 供应商 Cookie 会话捕获与外部配额(Token Harbor / 小米 MiMo / River / ModelScope 魔搭 / LongCat)",
5
5
  "homepage": "https://github.com/techysy/CreditDaddy",
6
6
  "repository": {
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 45 45" shape-rendering="crispEdges"><path stroke="#d4b83a" d="M2 2.5h7m1 0h2m2 0h2m1 0h2m2 0h2m1 0h6m2 0h2m2 0h7M2 3.5h1m5 0h1m1 0h1m2 0h1m1 0h2m1 0h3m1 0h1m3 0h4m1 0h1m2 0h1m1 0h1m5 0h1M2 4.5h1m1 0h3m1 0h1m2 0h1m3 0h4m1 0h3m4 0h1m2 0h2m1 0h1m2 0h1m1 0h3m1 0h1M2 5.5h1m1 0h3m1 0h1m1 0h1m1 0h2m1 0h1m4 0h1m1 0h3m2 0h5m1 0h1m2 0h1m1 0h3m1 0h1M2 6.5h1m1 0h3m1 0h1m1 0h2m1 0h2m1 0h1m5 0h5m1 0h2m6 0h1m1 0h3m1 0h1M2 7.5h1m5 0h1m1 0h1m5 0h1m3 0h1m1 0h1m1 0h1m1 0h1m1 0h3m2 0h2m1 0h1m5 0h1M2 8.5h7m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h7M11 9.5h2m2 0h1m1 0h1m1 0h1m4 0h2m2 0h7M5 10.5h1m2 0h1m4 0h3m1 0h2m1 0h2m1 0h2m1 0h3m1 0h1m3 0h1m2 0h3m1 0h2M5 11.5h1m1 0h1m1 0h2m1 0h4m2 0h2m4 0h2m2 0h1m1 0h1m1 0h1m1 0h3m2 0h3M2 12.5h1m1 0h3m1 0h2m1 0h1m3 0h1m2 0h1m1 0h1m1 0h1m1 0h1m2 0h2m2 0h3m3 0h4M4 13.5h4m1 0h2m1 0h2m1 0h1m2 0h1m1 0h3m2 0h2m2 0h2m1 0h1m4 0h1m2 0h1M5 14.5h1m2 0h3m5 0h1m2 0h1m1 0h3m2 0h2m1 0h1m1 0h1m1 0h2m1 0h1m2 0h1m2 0h1M2 15.5h2m5 0h1m2 0h2m1 0h2m4 0h1m1 0h1m1 0h1m3 0h2m1 0h1m1 0h1m1 0h1m4 0h1M3 16.5h2m1 0h8m2 0h1m1 0h1m1 0h3m1 0h2m5 0h3m2 0h1m2 0h1m1 0h2M3 17.5h2m1 0h2m2 0h3m2 0h1m3 0h2m1 0h2m1 0h3m1 0h1m1 0h2m1 0h1m1 0h2m3 0h1M4 18.5h1m2 0h4m1 0h1m1 0h2m2 0h1m1 0h2m4 0h2m2 0h2m5 0h1M2 19.5h1m1 0h1m1 0h1m2 0h2m1 0h1m2 0h1m1 0h5m2 0h5m1 0h2m4 0h2m1 0h1m1 0h2M3 20.5h2m1 0h1m1 0h1m1 0h4m1 0h3m2 0h4m1 0h1m4 0h2m2 0h2m2 0h5M3 21.5h3m1 0h1m1 0h2m2 0h1m1 0h1m1 0h3m1 0h2m1 0h4m1 0h1m4 0h1m2 0h1m1 0h1m1 0h2M2 22.5h3m1 0h4m1 0h2m1 0h1m1 0h4m1 0h1m2 0h2m1 0h2m2 0h1m1 0h1m1 0h4m1 0h1m1 0h1M4 23.5h2m3 0h1m1 0h1m4 0h2m4 0h2m7 0h1m2 0h3m1 0h1m1 0h3M2 24.5h3m1 0h1m1 0h3m1 0h1m1 0h1m1 0h3m1 0h3m2 0h3m2 0h4m1 0h1m3 0h1m1 0h1M2 25.5h2m3 0h1m4 0h1m3 0h2m3 0h1m1 0h1m2 0h1m2 0h1m6 0h3M2 26.5h1m1 0h1m2 0h2m5 0h2m1 0h1m1 0h4m1 0h2m1 0h1m2 0h8m2 0h2M2 27.5h4m1 0h1m1 0h1m1 0h1m2 0h1m1 0h3m2 0h4m2 0h2m4 0h1m5 0h1M3 28.5h3m2 0h3m1 0h2m2 0h2m3 0h1m4 0h2m3 0h2m1 0h2m1 0h2m3 0h1M4 29.5h2m4 0h2m1 0h2m2 0h4m1 0h3m1 0h1m1 0h2m1 0h1m2 0h5m2 0h1M3 30.5h1m1 0h1m2 0h2m2 0h1m1 0h1m7 0h2m3 0h1m3 0h2m2 0h2m4 0h1M3 31.5h2m1 0h1m5 0h3m1 0h1m1 0h2m7 0h1m1 0h7m1 0h1m1 0h1m2 0h1M2 32.5h1m1 0h1m2 0h4m3 0h1m4 0h3m5 0h1m1 0h4m6 0h2m1 0h1M4 33.5h1m4 0h2m1 0h2m1 0h3m2 0h1m2 0h1m1 0h3m3 0h2m2 0h1m2 0h1m3 0h1M2 34.5h1m2 0h5m2 0h1m3 0h2m3 0h1m1 0h1m4 0h3m3 0h5m1 0h1m1 0h1M10 35.5h2m4 0h1m3 0h1m1 0h1m3 0h1m1 0h1m1 0h5m3 0h1m1 0h1m1 0h1M2 36.5h7m3 0h2m1 0h2m3 0h3m3 0h1m1 0h1m3 0h1m1 0h1m1 0h1m1 0h4M2 37.5h1m5 0h1m3 0h4m6 0h3m2 0h4m1 0h1m1 0h1m3 0h1m1 0h1M2 38.5h1m1 0h3m1 0h1m2 0h1m4 0h3m1 0h2m1 0h1m2 0h1m5 0h1m1 0h5M2 39.5h1m1 0h3m1 0h1m1 0h2m2 0h1m4 0h5m2 0h2m2 0h1m1 0h1m2 0h2m1 0h1m2 0h1M2 40.5h1m1 0h3m1 0h1m2 0h2m4 0h2m3 0h1m3 0h1m1 0h1m9 0h2m2 0h1M2 41.5h1m5 0h1m2 0h2m1 0h1m3 0h7m1 0h2m1 0h1m1 0h1m1 0h2m1 0h2m1 0h1m1 0h1M2 42.5h7m2 0h1m3 0h4m2 0h2m1 0h2m2 0h1m2 0h1m1 0h3m1 0h2m1 0h2"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 37 37" shape-rendering="crispEdges"><path stroke="#d4b83a" d="M2 2.5h7m2 0h1m1 0h1m2 0h6m2 0h1m1 0h1m1 0h7M2 3.5h1m5 0h1m1 0h1m1 0h2m1 0h3m2 0h1m2 0h2m3 0h1m5 0h1M2 4.5h1m1 0h3m1 0h1m1 0h2m1 0h1m3 0h1m1 0h1m1 0h4m1 0h1m1 0h1m1 0h3m1 0h1M2 5.5h1m1 0h3m1 0h1m1 0h1m1 0h1m1 0h5m3 0h4m2 0h1m1 0h3m1 0h1M2 6.5h1m1 0h3m1 0h1m1 0h1m1 0h2m1 0h1m2 0h1m3 0h1m1 0h2m2 0h1m1 0h3m1 0h1M2 7.5h1m5 0h1m1 0h1m2 0h1m1 0h1m2 0h2m1 0h5m2 0h1m5 0h1M2 8.5h7m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h7M11 9.5h2m2 0h3m1 0h1m1 0h1m2 0h3M4 10.5h1m2 0h5m1 0h1m13 0h1m1 0h5M2 11.5h1m2 0h1m1 0h1m3 0h2m2 0h4m2 0h1m2 0h1m1 0h4m1 0h2m1 0h1M3 12.5h1m4 0h5m7 0h2m1 0h3m1 0h1m1 0h2m1 0h1m1 0h1M2 13.5h1m1 0h2m3 0h2m1 0h1m6 0h1m1 0h2m1 0h1m1 0h2m1 0h1m3 0h1M4 14.5h1m2 0h4m3 0h1m1 0h1m1 0h3m2 0h4m1 0h2m1 0h1m1 0h2M2 15.5h4m1 0h1m2 0h1m4 0h2m1 0h1m3 0h4m2 0h2m2 0h1m1 0h1M7 16.5h3m2 0h3m4 0h2m4 0h2m3 0h1m1 0h1m1 0h1M3 17.5h2m2 0h1m2 0h1m1 0h5m1 0h3m3 0h5m2 0h1m1 0h2M2 18.5h1m2 0h2m1 0h2m2 0h1m1 0h3m1 0h2m2 0h1m1 0h1m3 0h2M2 19.5h6m1 0h1m5 0h8m2 0h1m1 0h2m3 0h1m1 0h1M2 20.5h1m1 0h2m1 0h2m1 0h2m2 0h1m2 0h1m3 0h1m2 0h2m4 0h3m1 0h1M2 21.5h6m1 0h1m2 0h2m1 0h1m4 0h3m1 0h2m2 0h1m2 0h1M3 22.5h1m1 0h1m1 0h7m2 0h4m2 0h1m2 0h2m1 0h2m3 0h1M3 23.5h1m1 0h1m1 0h1m1 0h2m2 0h2m3 0h2m2 0h1m5 0h2m1 0h1m2 0h1M2 24.5h3m1 0h1m1 0h1m1 0h3m1 0h1m2 0h3m2 0h1m1 0h2m1 0h5m2 0h1M6 25.5h2m3 0h2m1 0h1m2 0h2m1 0h1m1 0h1m1 0h3m2 0h1m1 0h1m1 0h2M2 26.5h2m2 0h3m1 0h1m2 0h4m3 0h2m3 0h7M10 27.5h1m3 0h2m1 0h3m1 0h3m1 0h2m3 0h3m1 0h1M2 28.5h7m1 0h2m1 0h1m1 0h1m1 0h1m2 0h1m1 0h1m3 0h1m1 0h1m1 0h1m3 0h1M2 29.5h1m5 0h1m1 0h2m1 0h1m1 0h1m6 0h2m1 0h2m3 0h2m1 0h2M2 30.5h1m1 0h3m1 0h1m3 0h2m1 0h1m2 0h2m2 0h2m1 0h7M2 31.5h1m1 0h3m1 0h1m2 0h2m2 0h2m6 0h1m1 0h1m1 0h1m1 0h2m1 0h2M2 32.5h1m1 0h3m1 0h1m1 0h1m4 0h1m2 0h1m1 0h6m4 0h1m1 0h3M2 33.5h1m5 0h1m6 0h3m1 0h1m3 0h2m1 0h1m4 0h1M2 34.5h7m5 0h2m1 0h2m2 0h1m2 0h1m1 0h1m1 0h1m1 0h2m2 0h1"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 45 45" shape-rendering="crispEdges"><path stroke="#d4b83a" d="M2 2.5h7m7 0h1m1 0h2m1 0h3m1 0h2m3 0h3m3 0h7M2 3.5h1m5 0h1m3 0h4m4 0h1m1 0h2m1 0h1m5 0h3m2 0h1m5 0h1M2 4.5h1m1 0h3m1 0h1m1 0h1m1 0h1m1 0h2m1 0h1m3 0h4m1 0h1m2 0h1m4 0h1m1 0h1m1 0h3m1 0h1M2 5.5h1m1 0h3m1 0h1m1 0h1m1 0h1m5 0h2m1 0h6m3 0h1m1 0h3m1 0h1m1 0h3m1 0h1M2 6.5h1m1 0h3m1 0h1m2 0h1m1 0h2m1 0h1m1 0h1m2 0h3m1 0h1m2 0h1m1 0h3m3 0h1m1 0h3m1 0h1M2 7.5h1m5 0h1m2 0h2m3 0h5m5 0h2m6 0h1m1 0h1m5 0h1M2 8.5h7m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h7M17 9.5h2m3 0h1m2 0h1m3 0h1m2 0h1M5 10.5h2m1 0h2m1 0h2m2 0h1m1 0h2m1 0h4m1 0h1m3 0h1m1 0h3m5 0h2M6 11.5h2m3 0h1m4 0h1m3 0h1m2 0h1m4 0h4m1 0h1m1 0h1m1 0h5M2 12.5h4m1 0h2m1 0h1m3 0h1m3 0h2m1 0h2m2 0h1m3 0h4m1 0h3m1 0h2m1 0h1M2 13.5h3m2 0h1m2 0h1m1 0h1m1 0h1m1 0h1m6 0h1m1 0h1m5 0h3m3 0h3M2 14.5h2m4 0h2m3 0h2m1 0h1m1 0h2m4 0h1m1 0h1m1 0h1m4 0h2m1 0h1M4 15.5h2m3 0h3m1 0h5m2 0h1m1 0h2m2 0h3m2 0h1m3 0h2m1 0h2m2 0h1M2 16.5h3m3 0h3m1 0h3m1 0h2m2 0h2m1 0h3m3 0h1m2 0h2m4 0h1m3 0h1M2 17.5h1m1 0h3m4 0h1m3 0h2m1 0h1m2 0h2m1 0h4m2 0h1m1 0h1m2 0h1m2 0h3M2 18.5h3m2 0h2m1 0h1m4 0h3m1 0h1m1 0h1m4 0h2m1 0h1m4 0h2m1 0h1m1 0h4M2 19.5h1m2 0h1m1 0h1m2 0h1m1 0h3m1 0h3m1 0h1m4 0h2m2 0h1m2 0h1m1 0h1m2 0h4M2 20.5h3m1 0h1m1 0h2m1 0h2m1 0h1m4 0h2m2 0h3m1 0h3m3 0h2m1 0h2m1 0h1m2 0h1M3 21.5h3m1 0h1m3 0h2m1 0h2m4 0h3m4 0h1m1 0h7m4 0h2M2 22.5h3m2 0h2m4 0h1m1 0h1m4 0h4m1 0h1m2 0h3m4 0h3m1 0h4M2 23.5h3m6 0h1m1 0h1m2 0h2m1 0h2m2 0h2m1 0h3m3 0h1m2 0h1m1 0h5M4 24.5h3m1 0h1m1 0h1m1 0h1m1 0h2m2 0h1m1 0h1m6 0h3m1 0h2m1 0h5M6 25.5h1m4 0h1m1 0h1m4 0h5m2 0h3m1 0h1m1 0h2m1 0h1m3 0h2m1 0h2M4 26.5h1m2 0h3m2 0h2m1 0h1m2 0h10m1 0h3m4 0h2m4 0h1M3 27.5h2m2 0h1m1 0h1m1 0h1m1 0h1m4 0h2m2 0h1m1 0h1m1 0h3m1 0h1m3 0h1m1 0h4M2 28.5h1m2 0h1m1 0h3m1 0h2m2 0h1m2 0h1m1 0h4m2 0h1m2 0h5m2 0h1m2 0h1m2 0h1M2 29.5h1m1 0h1m4 0h1m1 0h1m1 0h1m2 0h5m1 0h3m2 0h4m2 0h1m4 0h3m1 0h1M8 30.5h1m3 0h2m2 0h1m1 0h1m1 0h2m5 0h1m1 0h1m1 0h1m6 0h2M2 31.5h1m2 0h1m1 0h1m2 0h1m3 0h1m1 0h1m3 0h1m3 0h2m6 0h3m1 0h1m1 0h2m1 0h2M2 32.5h5m1 0h1m1 0h1m1 0h1m2 0h1m3 0h3m2 0h1m3 0h1m1 0h1m1 0h3m2 0h2m1 0h1m1 0h1M2 33.5h4m4 0h1m3 0h2m1 0h1m1 0h1m2 0h2m2 0h1m2 0h2m1 0h1m2 0h4m1 0h2M2 34.5h3m1 0h1m1 0h2m3 0h2m2 0h2m2 0h1m2 0h2m2 0h1m1 0h1m2 0h7M10 35.5h1m2 0h4m4 0h2m1 0h1m3 0h1m3 0h3m3 0h1m1 0h1M2 36.5h7m1 0h1m3 0h1m2 0h1m1 0h3m2 0h1m1 0h2m1 0h1m1 0h4m1 0h1m1 0h3M2 37.5h1m5 0h1m3 0h1m1 0h1m2 0h4m2 0h6m2 0h1m2 0h1m3 0h2m1 0h2M2 38.5h1m1 0h3m1 0h1m1 0h2m5 0h1m2 0h3m1 0h1m1 0h2m3 0h10m1 0h1M2 39.5h1m1 0h3m1 0h1m1 0h3m1 0h3m1 0h2m5 0h1m1 0h3m5 0h1m1 0h1m1 0h4M2 40.5h1m1 0h3m1 0h1m2 0h1m1 0h2m2 0h1m3 0h1m1 0h1m2 0h2m1 0h5m1 0h1m2 0h1m1 0h3M2 41.5h1m5 0h1m2 0h2m1 0h6m1 0h1m2 0h4m1 0h1m2 0h1m1 0h1m1 0h1m1 0h3m1 0h1M2 42.5h7m3 0h1m2 0h1m2 0h2m1 0h1m1 0h1m2 0h5m1 0h4m1 0h2"/></svg>
package/src/checkin.js CHANGED
@@ -224,13 +224,12 @@ async function runTickNow(opts) {
224
224
 
225
225
  async function runTickInner(opts) {
226
226
  const allAccounts = await loadAccounts();
227
- // WB 国际版活跃请求全局开关(面板「设置 → 通用」):关闭时该轮与手动领取都不再打
228
- const wbActivity = (await loadSettings()).workbuddyActivity !== false;
227
+ // workbuddy-intl 无 checkin 动作(providers.js 的 intl 分支已删),providers 过滤天然跳过;
228
+ // 「活跃请求」全局开关随该机制一并删除(设置项不再读写)
229
229
  const accounts = allAccounts.filter(
230
230
  (a) => (!opts.provider || a.provider === opts.provider)
231
231
  && (!opts.product || productOf(a.provider) === opts.product)
232
232
  && (!opts.onlyAccountId || a.id === opts.onlyAccountId)
233
- && (wbActivity || a.provider !== 'workbuddy-intl')
234
233
  && typeof productImpl(a.provider)?.checkin === 'function'
235
234
  );
236
235
  const zAccounts = (opts.includeZcode !== false && autoClaimEnabled()
@@ -333,16 +332,18 @@ async function runTickInner(opts) {
333
332
  const limited = results.filter((r) => r.status === 'limited');
334
333
  const already = results.length - claimed.length - failed.length - none.length - limited.length;
335
334
  const totalCredits = claimed.reduce((sum, r) => sum + (r.claimedAmount || 0), 0);
335
+ const summaryKey = limited.length
336
+ ? '签到汇总:成功 {ok}(+{credits} Credits)、已领 {al}、本机限领 {limited}、无活动 {none}、失败 {fail}'
337
+ : '签到汇总:成功 {ok}(+{credits} Credits)、已领 {al}、无活动 {none}、失败 {fail}';
338
+ const summaryArgs = { ok: claimed.length, credits: totalCredits, al: already, limited: limited.length, none: none.length, fail: failed.length };
339
+ // 摘要走 i18n 模板(key+args,面板按界面语言 T() 渲染,与日志同源同语);
340
+ // summary 保留简中拼接兜底旧面板/CLI 直读(不再被面板展示路径使用)
336
341
  const summary = `签到汇总:成功 ${claimed.length}(+${totalCredits} Credits)、已领 ${already}`
337
342
  + (limited.length ? `、本机限领 ${limited.length}` : '')
338
343
  + `、无活动 ${none.length}、失败 ${failed.length}`;
339
- // 日志走 key+args(按界面语言实时重渲染);summary 原文继续供面板/状态展示
340
- logger.info('CHECKIN', limited.length
341
- ? '签到汇总:成功 {ok}(+{credits} Credits)、已领 {al}、本机限领 {limited}、无活动 {none}、失败 {fail}'
342
- : '签到汇总:成功 {ok}(+{credits} Credits)、已领 {al}、无活动 {none}、失败 {fail}',
343
- { ok: claimed.length, credits: totalCredits, al: already, limited: limited.length, none: none.length, fail: failed.length });
344
- lastTick = { at: new Date().toISOString(), summary };
345
- return { results, summary };
344
+ logger.info('CHECKIN', summaryKey, summaryArgs);
345
+ lastTick = { at: new Date().toISOString(), summary, summaryKey, summaryArgs };
346
+ return { results, summary, summaryKey, summaryArgs };
346
347
  }
347
348
 
348
349
  async function scheduleTick() {
package/src/constants.js CHANGED
@@ -35,7 +35,7 @@ export const WEB_USAGE_PATH = '/api/v2/me/usages/big_model_credits';
35
35
  export const JOB_TOKEN_EXCHANGE_PATH = '/api/v1/jobToken/exchange';
36
36
 
37
37
  // 账号的 provider = 产品 + 区域。新增产品时在此登记,并在 providers.js 挂上对应实现。
38
- export const PROVIDERS = ['qoder', 'qoder-cn', 'workbuddy', 'workbuddy-intl', 'zcode', 'mirasim', 'catpaw', 'trae', 'minimax', 'tokenharbor', 'xiaomi-mimo', 'river', 'modelscope', 'longcat'];
38
+ export const PROVIDERS = ['qoder', 'qoder-cn', 'workbuddy', 'workbuddy-intl', 'zcode', 'mirasim', 'catpaw', 'trae', 'minimax', 'tokenharbor', 'xiaomi-mimo', 'river', 'modelscope', 'longcat', 'doubao'];
39
39
  export const PROVIDER_LABEL = {
40
40
  qoder: 'Qoder 国际版',
41
41
  'qoder-cn': 'Qoder 国内版',
@@ -51,6 +51,7 @@ export const PROVIDER_LABEL = {
51
51
  river: 'River AI',
52
52
  modelscope: 'ModelScope 魔搭',
53
53
  longcat: 'LongCat',
54
+ doubao: '豆包',
54
55
  };
55
56
  /** provider → 产品线(qoder / workbuddy / zcode / mirasim / catpaw / trae / minimax / tokenharbor / xiaomi-mimo / river) */
56
57
  export const productOf = (provider) => {
@@ -66,6 +67,7 @@ export const productOf = (provider) => {
66
67
  if (p === 'river') return 'river';
67
68
  if (p === 'modelscope') return 'modelscope';
68
69
  if (p === 'longcat') return 'longcat';
70
+ if (p === 'doubao') return 'doubao';
69
71
  return 'qoder';
70
72
  };
71
73
  /** provider 是否国内版 */
@@ -65,7 +65,7 @@ export const COOKIE_SITES = [
65
65
  id: 'tokenharbor',
66
66
  name: 'Token Harbor',
67
67
  provider: 'tokenharbor',
68
- label: 'Token Harbor 免费额度',
68
+ label: 'Token Harbor',
69
69
  loginUrl: 'https://tokenharbor.ai/login',
70
70
  homeUrl: 'https://tokenharbor.ai',
71
71
  // 探测标记:由于 Token Harbor 的 dashboard 页面将 Free allowance 移至客户端动态组件中渲染,
@@ -86,14 +86,14 @@ export const COOKIE_SITES = [
86
86
  },
87
87
  // issue #24:捕获时顺手解析网页读数,存 meta.quotaSnapshot 供额度推送消费
88
88
  quota: { fromHtml: parseTokenHarborQuota },
89
- accountName: 'Token Harbor 网页会话',
89
+ accountName: 'Token Harbor',
90
90
  hint: '登录后 dashboard 才有 Free allowance 配额;凭据只存本机(账号库加密),同步到 10Router 时按 creditDaddyWebSession 形状传输。',
91
91
  },
92
92
  {
93
93
  id: 'xiaomi-mimo',
94
94
  name: 'Xiaomi MiMo',
95
95
  provider: 'xiaomi-mimo',
96
- label: '小米 MiMo 控制台余额',
96
+ label: '小米 MiMo',
97
97
  loginUrl: 'https://platform.xiaomimimo.com/console/balance',
98
98
  homeUrl: 'https://platform.xiaomimimo.com',
99
99
  probe: {
@@ -101,21 +101,21 @@ export const COOKIE_SITES = [
101
101
  match: 'userId',
102
102
  accept: 'application/json, text/plain, */*',
103
103
  },
104
- accountName: '小米 MiMo 控制台会话',
104
+ accountName: '小米 MiMo',
105
105
  hint: '登录后自动抓取 UID 与控制台充值余额;通过外部配额(issue #24/26)推送到 10Router 配额追踪器显示余额卡片。',
106
106
  },
107
107
  {
108
108
  id: 'modelscope',
109
109
  name: 'ModelScope 魔搭',
110
110
  provider: 'modelscope',
111
- label: 'ModelScope 魔方余额',
111
+ label: 'ModelScope',
112
112
  loginUrl: 'https://modelscope.cn',
113
113
  homeUrl: 'https://modelscope.cn',
114
114
  // 魔方余额 API 本身就是探测(GET /openapi/v1/magicubes/balance 带会话 cookie);
115
115
  // 每日魔方额度为登录自动发放(前端无 claim 端点),故无签到自动化,只读余额出卡。
116
116
  cookieUrls: ['https://modelscope.cn', 'https://www.modelscope.cn'],
117
117
  verify: 'api',
118
- accountName: 'ModelScope 网页会话',
118
+ accountName: 'ModelScope',
119
119
  identity: { fromHtml: /[\w.+-]+@[\w-]+\.[\w.]+/ },
120
120
  hint: '登录魔搭后自动抓取魔方(Magicube)余额;每日额度自动发放无需签到,token 只存本机,余额数字推 10Router 出卡(同名认领可挂连接卡)。',
121
121
  },
@@ -123,7 +123,7 @@ export const COOKIE_SITES = [
123
123
  id: 'river',
124
124
  name: 'River AI',
125
125
  provider: 'river',
126
- label: 'River AI 免费额度',
126
+ label: 'River AI',
127
127
  loginUrl: 'https://console.river.ai',
128
128
  homeUrl: 'https://console.river.ai',
129
129
  // 凭据主体是 WorkOS 会话——实测(2026-10-14)SPA 的 token 只在内存 Map,localStorage
@@ -134,14 +134,14 @@ export const COOKIE_SITES = [
134
134
  storagePrefixes: ['workos:'],
135
135
  cookieUrls: ['https://console.river.ai', 'https://auth.console.river.ai', 'https://login.console.river.ai'],
136
136
  verify: 'api',
137
- accountName: 'River AI 网页会话',
137
+ accountName: 'River AI',
138
138
  hint: '登录 console.river.ai 后自动抓取 WorkOS 会话与 Billing 余额($25 免费额度);token 只存本机,推送 10Router 只带余额数字,会话过期自动刷新(单次轮换即时落盘)。',
139
139
  },
140
140
  {
141
141
  id: 'longcat',
142
142
  name: 'LongCat',
143
143
  provider: 'longcat',
144
- label: 'LongCat Token 资源包',
144
+ label: 'LongCat',
145
145
  loginUrl: 'https://longcat.chat/pc/login',
146
146
  homeUrl: 'https://longcat.chat',
147
147
  // 资源包汇总 API 即探测:带对 cookie 返 200 {code:0},未登录 401「用户未登录」(2026-10-15 实测)
@@ -151,9 +151,25 @@ export const COOKIE_SITES = [
151
151
  accept: 'application/json, text/plain, */*',
152
152
  },
153
153
  verify: 'api',
154
- accountName: 'LongCat 网页会话',
154
+ accountName: 'LongCat',
155
155
  hint: '登录 longcat.chat 后自动抓取 Token 资源包余量与逐包明细(当前包 + 其他包,按官方消耗顺序排列);推送 10Router 只带 token 数字,会话 cookie 只存本机。',
156
156
  },
157
+ {
158
+ id: 'doubao',
159
+ name: '豆包',
160
+ provider: 'doubao',
161
+ label: '豆包',
162
+ loginUrl: 'https://www.doubao.com',
163
+ homeUrl: 'https://www.doubao.com',
164
+ // 探测 = 任务面板数据接口本身(issue #32,2026-10-19/20 实测):POST detail 带会话 cookie
165
+ // 返 200 {code:0},未登录返 200 {code:710012001,"login invalid"}——用 match 判业务码而非 HTTP 状态。
166
+ // 活动页 UI 有「仅支持电脑版」前端墙,但接口不吃这套(纯 cookie 鉴权,无 a_bogus 签名)。
167
+ // 最终定位(用户拍板):豆包 = 纯「快速打开客户端」入口。网页会话 cookie 下 detail
168
+ // 返回残缺数据(额度恒 0、签到状态不可信),额度可见也做不实——不加会话捕获探测,
169
+ // 只在面板出示快捷按钮。
170
+ entryOnly: true, // 只出「打开豆包」按钮,无会话捕获 / 无探测 / 无账号行
171
+ hint: '在豆包客户端(或网页)登录后捕获会话,CD 只读展示体验额度与每日签到状态(+200/天);签到请在「打开豆包」里手动完成——活动在客户端内,CD 不代签;仅个人账号可参与(飞书企业号被排除),凭据只存本机。'
172
+ }
157
173
  ];
158
174
 
159
175
  export const getSite = (id) => COOKIE_SITES.find((s) => s.id === id) || null;
@@ -187,13 +203,16 @@ function testProbeMatch(site, text) {
187
203
  /**
188
204
  * 探测一份会话 cookie 是否仍然有效。
189
205
  * 探测走 fetchJsonRace(跟随全局代理配置——Token Harbor 对大陆/港澳有封锁,出口代理是必须项)。
206
+ * probe 支持 method / body(JSON API 探测,如豆包的 POST detail 接口——GET 打不到任务数据)。
190
207
  * @returns {Promise<{ok: boolean, reason?: 'invalid'|'no-match'|'http'|'network', status?: number, html?: string}>}
191
208
  */
192
209
  export async function verifySiteCookie(site, cookie, { fetchImpl } = {}) {
193
210
  const url = probeUrl(site);
194
- const doFetch = fetchImpl || ((u, init) => fetchJsonRace(u, { headers: init.headers, timeoutMs: 12000 }));
211
+ const method = site.probe?.method || 'GET';
212
+ const doFetch = fetchImpl || ((u, init) => fetchJsonRace(u, { headers: init.headers, method, body: site.probe?.body || undefined, timeoutMs: 12000, preferProxy: site.probe?.preferProxy === true }));
195
213
  try {
196
214
  const headers = { ...dashboardHeaders(site), Cookie: String(cookie || '') };
215
+ if (site.probe?.body) headers['Content-Type'] = headers['Content-Type'] || 'application/json';
197
216
  const r = await doFetch(url, { headers });
198
217
  if (r.status === 401 || r.status === 403) return { ok: false, reason: 'invalid', status: r.status };
199
218
  if (r.status !== 200) return { ok: false, reason: 'http', status: r.status };