@gehennawu/dsh-service 1.4.4 → 1.4.8

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/index.js CHANGED
@@ -5439,6 +5439,51 @@ function apply(ctx) {
5439
5439
  return rpcTechnicalFailure(error)
5440
5440
  }
5441
5441
  } },
5442
+ 'sessions-clear-deleted': { feature: 'sessionManager', audit: true, handle: async (payload, rpcEndpoint) => {
5443
+ const all = payload?.all === true
5444
+ const raw = Array.isArray(payload?.ids) ? payload.ids : []
5445
+ const ids = []
5446
+ const seen = new Set()
5447
+ for (const id of raw) {
5448
+ if (typeof id !== 'string' || id.trim() === '') continue
5449
+ const cleanId = id.trim()
5450
+ if (seen.has(cleanId)) continue
5451
+ seen.add(cleanId)
5452
+ ids.push(cleanId)
5453
+ }
5454
+ if (!all && ids.length === 0) return rpcFailure(new Error('invalid-session-ids'))
5455
+ try {
5456
+ const deleted = await loadDeletedSessions(dshHome)
5457
+ let removedCount = 0
5458
+ const removedIds = []
5459
+ if (all) {
5460
+ removedCount = deleted.items.length
5461
+ for (const item of deleted.items) removedIds.push(item.id)
5462
+ deleted.items = []
5463
+ } else {
5464
+ const targetSet = new Set(ids)
5465
+ const remaining = []
5466
+ for (const item of deleted.items) {
5467
+ if (targetSet.has(item.id)) {
5468
+ removedCount++
5469
+ removedIds.push(item.id)
5470
+ } else {
5471
+ remaining.push(item)
5472
+ }
5473
+ }
5474
+ deleted.items = remaining
5475
+ }
5476
+ if (removedCount > 0) {
5477
+ await saveDeletedSessions(dshHome, deleted)
5478
+ }
5479
+ if (sessionTitleCache !== null) {
5480
+ for (const id of removedIds) sessionTitleCache.delete(id)
5481
+ }
5482
+ return { ok: true, value: { cleared: true, count: removedCount, ids: removedIds } }
5483
+ } catch (error) {
5484
+ return rpcTechnicalFailure(error)
5485
+ }
5486
+ } },
5442
5487
  }
5443
5488
  const dispatchRpc = createRpcDispatcher({ endpoints: rpcEndpoints, featureEnabled, logger: ctx.logger })
5444
5489
  ctx.connection.rpc.handle('/dsh-service', dispatchRpc, { authority: 'loopback' })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gehennawu/dsh-service",
3
- "version": "1.4.4",
3
+ "version": "1.4.8",
4
4
  "description": "DSH Web 运维面板:安全重启、健康监控、备份和 Linux 权限维护。",
5
5
  "type": "module",
6
6
  "scripts": {
package/quota-adapters.js CHANGED
@@ -542,12 +542,19 @@ async function fetchStepFunStepPlanUsage({ credential, signal, requestJson }) {
542
542
 
543
543
  const CLIPROXY_CODEX_USAGE_URL = 'https://chatgpt.com/backend-api/wham/usage'
544
544
  const CLIPROXY_GEMINI_QUOTA_URL = 'https://cloudcode-pa.googleapis.com/v1internal:retrieveUserQuota'
545
+ // antigravity 额度候选(v1.4.8 修订顺序):CPA 的 antigravity 流量默认全打 daily-cloudcode-pa
546
+ // (executor 源码 "Consumer credentials default to daily"),真实用量落在 daily 池;prod 池对同一
547
+ // 账号返回合法形状但近乎全空(2026-09-04 真机实测同一时刻 daily 5h≈38% vs prod 5h=0%,且 prod
548
+ // 的重置点全是 now+5h 滚动=从未消费的池子特征)。旧顺序 prod 先命中导致面板长期显示另一池的
549
+ // 数字。每层内部 daily 优先、prod 兜底;summary(组级 5h/周)→ fetchAvailableModels(模型级)→
550
+ // retrieveUserQuota(项目级,空 body 走账号默认项目)。
545
551
  const CLIPROXY_ANTIGRAVITY_QUOTA_URLS = [
546
- 'https://cloudcode-pa.googleapis.com/v1internal:retrieveUserQuotaSummary',
547
552
  'https://daily-cloudcode-pa.googleapis.com/v1internal:retrieveUserQuotaSummary',
548
- 'https://cloudcode-pa.googleapis.com/v1internal:retrieveUserQuota',
553
+ 'https://cloudcode-pa.googleapis.com/v1internal:retrieveUserQuotaSummary',
549
554
  'https://daily-cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels',
550
555
  'https://cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels',
556
+ 'https://daily-cloudcode-pa.googleapis.com/v1internal:retrieveUserQuota',
557
+ 'https://cloudcode-pa.googleapis.com/v1internal:retrieveUserQuota',
551
558
  ]
552
559
  const CLIPROXY_SUPPORTED_ACCOUNT_KINDS = new Set(['codex', 'gemini', 'gemini-cli', 'antigravity'])
553
560
  const CODEX_WINDOW_ORDER = new Map([
@@ -648,6 +655,20 @@ function parseCodexSignals(quota) {
648
655
  return sortCodexWindows(windows)
649
656
  }
650
657
 
658
+ /** 快照回退窗口(v1.3.1 复核修订):auth-files 内嵌 quota.signals 是 CPA 上次代调时缓存的
659
+ * 快照,age 无上界(实测部署可停在昨天)——只在对应账号实时 api-call 失败时代用。两道处理:
660
+ * ① 重置点已过的窗口是死数据(快照描述的窗口已结束),直接丢弃,绝不显示「重置时间在过去」;
661
+ * ② 其余窗口保留但打 stale 标记,客户端渲染「缓存」徽标,与实时窗口可区分。 */
662
+ function cliproxFallbackWindows(account, now = Date.now()) {
663
+ const usable = []
664
+ for (const window of account.fallbackWindows ?? []) {
665
+ const resetMs = typeof window.resetsAt === 'string' ? Date.parse(window.resetsAt) : Number(window.resetsAt)
666
+ if (Number.isFinite(resetMs) && resetMs <= now) continue
667
+ usable.push({ ...window, stale: true })
668
+ }
669
+ return usable
670
+ }
671
+
651
672
  function normalizeGeminiBuckets(buckets) {
652
673
  const windows = []
653
674
  if (!Array.isArray(buckets)) return windows
@@ -835,8 +856,9 @@ async function fetchCliproxyUsage({ profile, config, credential, signal, request
835
856
  })
836
857
  } catch (error) {
837
858
  failures.push({ index: accountIndex, code: quotaErrorCode(error) })
838
- if (account.fallbackWindows?.length > 0) {
839
- accountResults.set(accountIndex, account.fallbackWindows)
859
+ const fallback = cliproxFallbackWindows(account)
860
+ if (fallback.length > 0) {
861
+ accountResults.set(accountIndex, fallback)
840
862
  }
841
863
  return
842
864
  }
@@ -848,14 +870,16 @@ async function fetchCliproxyUsage({ profile, config, credential, signal, request
848
870
  }
849
871
  failures.push({ index: accountIndex, code: statusCode === 200 ? 'bad-payload:shape' : `upstream-status:${statusCode}` })
850
872
  if (account.provider !== 'antigravity') {
851
- if (account.fallbackWindows?.length > 0) {
852
- accountResults.set(accountIndex, account.fallbackWindows)
873
+ const fallback = cliproxFallbackWindows(account)
874
+ if (fallback.length > 0) {
875
+ accountResults.set(accountIndex, fallback)
853
876
  }
854
877
  return
855
878
  }
856
879
  }
857
- if (account.fallbackWindows?.length > 0) {
858
- accountResults.set(accountIndex, account.fallbackWindows)
880
+ const fallback = cliproxFallbackWindows(account)
881
+ if (fallback.length > 0) {
882
+ accountResults.set(accountIndex, fallback)
859
883
  } else {
860
884
  accountResults.set(accountIndex, [])
861
885
  }
@@ -883,6 +907,7 @@ async function fetchCliproxyUsage({ profile, config, credential, signal, request
883
907
  ...(account.label !== '' ? { label: account.label } : {}),
884
908
  percent: window.percent,
885
909
  ...(window.resetsAt !== undefined ? { resetsAt: window.resetsAt } : {}),
910
+ ...(window.stale === true ? { stale: true } : {}),
886
911
  })
887
912
  }
888
913
  }