@jxgame2020/dsh-token-quota 0.1.12 → 0.1.13

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/lib/client.js CHANGED
@@ -40,6 +40,7 @@ window.__ModuleLoader__.load({
40
40
  upgradeDismissed: false,
41
41
  checkingUpdates: false,
42
42
  lastCheckResult: "idle",
43
+ upgradeError: null,
43
44
  dialogOpen: false,
44
45
  fullNotice: null,
45
46
  reset: null,
@@ -86,6 +87,9 @@ window.__ModuleLoader__.load({
86
87
  setLastCheckResult: (d, result) => {
87
88
  d.lastCheckResult = result;
88
89
  },
90
+ setUpgradeError: (d, error) => {
91
+ d.upgradeError = error;
92
+ },
89
93
  setDialogOpen: (d, open) => {
90
94
  d.dialogOpen = open;
91
95
  },
@@ -166,7 +170,7 @@ window.__ModuleLoader__.load({
166
170
  }
167
171
  //#endregion
168
172
  //#region \0dsh-css:/Users/jxgame/Desktop/works/deepseek-harness-package/dsh-token-quota/packages/token-quota/src/client/TokenQuotaPanel.module.css.mjs
169
- const css = ".NPLLIq_panel{box-sizing:border-box;background:var(--dsw-alias-bg-overlay);border:1px solid var(--dsw-alias-border-l1);pointer-events:auto;z-index:40;border-radius:12px;flex-direction:column;width:320px;max-height:min(72vh,560px);display:flex;position:fixed;top:56px;right:12px;overflow:hidden;box-shadow:0 8px 28px #0000002e}.NPLLIq_header{border-bottom:1px solid var(--dsw-alias-border-l1);cursor:grab;user-select:none;touch-action:none;justify-content:space-between;align-items:flex-start;gap:8px;padding:10px 12px;display:flex}.NPLLIq_header:active{cursor:grabbing}.NPLLIq_headerText{flex-direction:column;gap:2px;min-width:0;display:flex}.NPLLIq_title{color:var(--dsw-alias-label-primary);align-items:baseline;gap:6px;font-size:13px;font-weight:600;display:flex}.NPLLIq_version{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:10px;font-weight:500}.NPLLIq_versionNew{color:var(--dsw-alias-status-warning-foreground,#b56900);background:var(--dsw-alias-status-warning-background,#fff6d7);cursor:default;border-radius:4px;padding:1px 6px}.NPLLIq_subtitle{color:var(--dsw-alias-label-secondary);font-size:11px}.NPLLIq_collapse{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;padding:2px 6px;font-size:11px}.NPLLIq_collapse:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_body{padding:4px 0;overflow-y:auto}.NPLLIq_row{border-bottom:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:6px;padding:8px 12px;display:flex}.NPLLIq_rowHeader{justify-content:space-between;align-items:center;gap:8px;display:flex}.NPLLIq_rowName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;align-items:center;gap:6px;font-size:12px;font-weight:500;display:inline-flex;overflow:hidden}.NPLLIq_currentBadge{color:var(--dsw-alias-state-success-primary);border:1px solid var(--dsw-alias-state-success-primary);border-radius:8px;flex:none;padding:1px 6px;font-size:10px}.NPLLIq_rowMeta{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex:none;font-size:11px}.NPLLIq_bar{background:var(--dsw-alias-bg-layer-1);border-radius:3px;height:6px;overflow:hidden}.NPLLIq_fillIdle{background:var(--dsw-alias-brand-primary);height:100%;transition:width .2s}.NPLLIq_fillWarn{background:var(--dsw-alias-state-warn-primary);height:100%;transition:width .2s}.NPLLIq_fillOver{background:var(--dsw-alias-state-error-primary);height:100%;transition:width .2s}.NPLLIq_controls{align-items:center;gap:6px;display:flex}.NPLLIq_input{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);min-width:0;color:var(--dsw-alias-label-primary);border-radius:6px;flex:1;padding:4px 8px;font-size:11px}.NPLLIq_input::placeholder{color:var(--dsw-alias-label-secondary)}.NPLLIq_save,.NPLLIq_switch{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;flex:none;padding:4px 10px;font-size:11px}.NPLLIq_save:hover,.NPLLIq_switch:hover:not(:disabled){background:var(--dsw-alias-bg-layer-2)}.NPLLIq_switch:disabled{opacity:.5;cursor:default}.NPLLIq_notice,.NPLLIq_noticeError{color:var(--dsw-alias-label-secondary);padding:10px 12px;font-size:12px}.NPLLIq_noticeError{color:var(--dsw-alias-state-error-primary)}.NPLLIq_tab{background:var(--dsw-alias-brand-primary);border:1px solid var(--dsw-alias-brand-primary);color:var(--dsw-alias-bg-overlay);pointer-events:auto;cursor:pointer;z-index:90;border-radius:10px;align-items:center;gap:6px;padding:9px 14px;font-size:12px;font-weight:600;display:inline-flex;position:fixed;top:56px;right:12px;box-shadow:0 6px 20px #00000040}.NPLLIq_tab:hover{filter:brightness(1.08)}.NPLLIq_tabIcon{font-size:12px;line-height:1}.NPLLIq_tabLabel{white-space:nowrap}.NPLLIq_headerActions{flex:none;align-items:center;gap:4px;display:flex}.NPLLIq_settingsBtn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;padding:2px 6px;font-size:11px}.NPLLIq_settingsBtn:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_selectBtn{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-brand-primary);cursor:pointer;background:0 0;border-radius:6px;flex:none;padding:1px 6px;font-size:10px}.NPLLIq_selectBtn:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_gearBtn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;flex:none;margin-left:6px;padding:0 2px;font-size:12px;line-height:1}.NPLLIq_gearBtn:hover{color:var(--dsw-alias-label-primary)}.NPLLIq_fullNotice{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-state-error-primary);border-radius:8px;margin:6px 12px;padding:8px 10px;font-size:12px}.NPLLIq_upgradeBanner{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-divider-1,#0000001a);border-radius:8px;margin:6px 12px;padding:10px 30px 10px 10px;font-size:12px;position:relative}.NPLLIq_upgradeBannerText{margin-bottom:6px;font-weight:600}.NPLLIq_upgradeCommands{flex-direction:column;gap:4px;display:flex}.NPLLIq_upgradeCommandRow{align-items:center;gap:6px;display:flex}.NPLLIq_upgradeCommand{background:var(--dsw-alias-bg-layer-2,#0000000a);white-space:nowrap;border-radius:4px;flex:1;min-width:0;padding:4px 6px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;overflow-x:auto}.NPLLIq_copyBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;flex:none;padding:3px 8px;font-size:11px}.NPLLIq_copyBtn:hover{background:var(--dsw-alias-bg-layer-3,#00000014)}.NPLLIq_upgradeHint{color:var(--dsw-alias-label-secondary);margin-top:6px;font-size:11px}.NPLLIq_upgradeClose{width:20px;height:20px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;font-size:16px;line-height:1;position:absolute;top:4px;right:6px}.NPLLIq_upgradeClose:hover{background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary)}.NPLLIq_checkUpdatesRow{justify-content:space-between;align-items:center;gap:12px;display:flex}.NPLLIq_checkUpdatesLabel{color:var(--dsw-alias-label-primary);cursor:pointer;align-items:center;gap:6px;font-size:12px;display:flex}.NPLLIq_checkUpdatesLabel input{margin:0}.NPLLIq_checkBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;white-space:nowrap;text-align:center;border-radius:4px;flex:none;min-width:72px;padding:4px 10px;font-size:12px}.NPLLIq_checkBtn:hover:not(:disabled){background:var(--dsw-alias-bg-layer-3,#00000014)}.NPLLIq_checkBtn:disabled{opacity:.6;cursor:default}.NPLLIq_dialog{z-index:100;box-sizing:border-box;background:var(--dsw-alias-bg-overlay);border:1px solid var(--dsw-alias-border-l1);border-radius:12px;flex-direction:column;gap:12px;width:280px;max-height:80vh;padding:14px;display:flex;position:fixed;top:50%;left:50%;overflow-y:auto;transform:translate(-50%,-50%);box-shadow:0 8px 28px #00000040}.NPLLIq_dialogTitle{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.NPLLIq_dialogSection{flex-direction:column;gap:6px;display:flex}.NPLLIq_dialogLabel{color:var(--dsw-alias-label-primary);font-size:12px;font-weight:500}.NPLLIq_monitorHint{color:var(--dsw-alias-label-secondary);font-size:11px}.NPLLIq_monitorList{flex-direction:column;gap:2px;max-height:180px;display:flex;overflow-y:auto}.NPLLIq_monitorRow{color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:6px;padding:2px 4px;font-size:12px;display:flex}.NPLLIq_monitorRow:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_monitorName{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.NPLLIq_radioRow{color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:6px;padding:3px 4px;font-size:12px;display:flex}.NPLLIq_radioRow:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_dialogActions{justify-content:flex-end;gap:6px;display:flex}.NPLLIq_dialogBtn,.NPLLIq_dialogBtnPrimary{border:1px solid var(--dsw-alias-border-l1);cursor:pointer;border-radius:6px;padding:4px 12px;font-size:11px}.NPLLIq_dialogBtn{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)}.NPLLIq_dialogBtnPrimary{background:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-bg-overlay)}.NPLLIq_dialogHeader{z-index:2;background:var(--dsw-alias-bg-overlay);cursor:grab;user-select:none;touch-action:none;justify-content:space-between;align-items:center;gap:8px;margin:-14px -14px 0;padding:14px 14px 8px;display:flex;position:sticky;top:-14px}.NPLLIq_dialogHeader:active{cursor:grabbing}.NPLLIq_dialogClose{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:8px;flex:none;justify-content:center;align-items:center;font-size:18px;line-height:1;display:flex}.NPLLIq_dialogClose:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_resetRow{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.NPLLIq_resetSelect{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:6px;padding:3px 6px;font-size:12px}.NPLLIq_logTable{border-collapse:collapse;width:100%;font-size:11px}.NPLLIq_logTable th{text-align:left;color:var(--dsw-alias-label-secondary);border-bottom:1px solid var(--dsw-alias-border-l1);padding:4px 6px;font-weight:500}.NPLLIq_logTable td{color:var(--dsw-alias-label-primary);border-bottom:1px solid var(--dsw-alias-border-l1);font-variant-numeric:tabular-nums;padding:4px 6px}.NPLLIq_logDayCol{white-space:nowrap;color:var(--dsw-alias-label-secondary)}.NPLLIq_logModelCol{text-overflow:ellipsis;white-space:nowrap;max-width:160px;overflow:hidden}.NPLLIq_logUsedCol{text-align:right}.NPLLIq_logDialog{gap:0;width:380px;max-height:min(72vh,480px);padding:0}.NPLLIq_logHeader{background:var(--dsw-alias-bg-overlay);cursor:grab;user-select:none;touch-action:none;flex:none;justify-content:space-between;align-items:center;gap:8px;padding:14px 14px 8px;display:flex}.NPLLIq_logHeader:active{cursor:grabbing}.NPLLIq_logScroll{flex:1;min-height:0;padding:0 14px 14px;overflow:auto}.NPLLIq_logToolbar{flex:1;align-items:center;gap:6px;display:flex}.NPLLIq_logSearch{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);min-width:0;color:var(--dsw-alias-label-primary);border-radius:4px;flex:1;padding:3px 6px;font-size:11px}.NPLLIq_logSearch:focus{border-color:var(--dsw-alias-accent-1,#4a9eff);outline:none}.NPLLIq_logClearBtn{border:1px solid var(--dsw-alias-state-error-border,#b400004d);color:var(--dsw-alias-state-error-primary,#c00);cursor:pointer;white-space:nowrap;background:0 0;border-radius:4px;flex:none;padding:3px 8px;font-size:11px}.NPLLIq_logClearBtn:hover{background:var(--dsw-alias-state-error-background,#ff00000f)}.NPLLIq_logPager{border-top:1px solid var(--dsw-alias-divider-1,#00000014);background:var(--dsw-alias-bg-overlay);color:var(--dsw-alias-label-secondary);flex:none;justify-content:space-between;align-items:center;gap:8px;padding:6px 14px;font-size:11px;display:flex}.NPLLIq_logPagerInfo{white-space:nowrap}.NPLLIq_logPagerControls{align-items:center;gap:4px;display:flex}.NPLLIq_logPagerBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);width:24px;height:24px;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;font-size:13px;line-height:1}.NPLLIq_logPagerBtn:disabled{opacity:.4;cursor:default}.NPLLIq_logPagerPages{text-align:center;min-width:50px;color:var(--dsw-alias-label-secondary)}.NPLLIq_logPageSizeSelect{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;padding:2px 4px;font-size:11px}.NPLLIq_dialogOverlay{z-index:100001;background:#0000004d;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.NPLLIq_logClearDialog{gap:0;width:320px;padding:16px}.NPLLIq_dialogBody{color:var(--dsw-alias-label-secondary);margin:6px 0 10px;font-size:12px;line-height:1.5}.NPLLIq_logClearDate{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);width:100%;color:var(--dsw-alias-label-primary);border-radius:6px;margin-bottom:12px;padding:6px 8px;font-size:13px}.NPLLIq_logClearDate:focus{border-color:var(--dsw-alias-accent-1,#4a9eff);outline:none}";
173
+ const css = ".NPLLIq_panel{box-sizing:border-box;background:var(--dsw-alias-bg-overlay);border:1px solid var(--dsw-alias-border-l1);pointer-events:auto;z-index:40;border-radius:12px;flex-direction:column;width:320px;max-height:min(72vh,560px);display:flex;position:fixed;top:56px;right:12px;overflow:hidden;box-shadow:0 8px 28px #0000002e}.NPLLIq_header{border-bottom:1px solid var(--dsw-alias-border-l1);cursor:grab;user-select:none;touch-action:none;justify-content:space-between;align-items:flex-start;gap:8px;padding:10px 12px;display:flex}.NPLLIq_header:active{cursor:grabbing}.NPLLIq_headerText{flex-direction:column;gap:2px;min-width:0;display:flex}.NPLLIq_title{color:var(--dsw-alias-label-primary);align-items:baseline;gap:6px;font-size:13px;font-weight:600;display:flex}.NPLLIq_version{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:10px;font-weight:500}.NPLLIq_versionNew{color:var(--dsw-alias-status-warning-foreground,#b56900);background:var(--dsw-alias-status-warning-background,#fff6d7);cursor:default;border-radius:4px;padding:1px 6px}.NPLLIq_subtitle{color:var(--dsw-alias-label-secondary);font-size:11px}.NPLLIq_collapse{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;padding:2px 6px;font-size:11px}.NPLLIq_collapse:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_body{padding:4px 0;overflow-y:auto}.NPLLIq_row{border-bottom:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:6px;padding:8px 12px;display:flex}.NPLLIq_rowHeader{justify-content:space-between;align-items:center;gap:8px;display:flex}.NPLLIq_rowName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;align-items:center;gap:6px;font-size:12px;font-weight:500;display:inline-flex;overflow:hidden}.NPLLIq_currentBadge{color:var(--dsw-alias-state-success-primary);border:1px solid var(--dsw-alias-state-success-primary);border-radius:8px;flex:none;padding:1px 6px;font-size:10px}.NPLLIq_rowMeta{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex:none;font-size:11px}.NPLLIq_bar{background:var(--dsw-alias-bg-layer-1);border-radius:3px;height:6px;overflow:hidden}.NPLLIq_fillIdle{background:var(--dsw-alias-brand-primary);height:100%;transition:width .2s}.NPLLIq_fillWarn{background:var(--dsw-alias-state-warn-primary);height:100%;transition:width .2s}.NPLLIq_fillOver{background:var(--dsw-alias-state-error-primary);height:100%;transition:width .2s}.NPLLIq_controls{align-items:center;gap:6px;display:flex}.NPLLIq_input{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);min-width:0;color:var(--dsw-alias-label-primary);border-radius:6px;flex:1;padding:4px 8px;font-size:11px}.NPLLIq_input::placeholder{color:var(--dsw-alias-label-secondary)}.NPLLIq_save,.NPLLIq_switch{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;flex:none;padding:4px 10px;font-size:11px}.NPLLIq_save:hover,.NPLLIq_switch:hover:not(:disabled){background:var(--dsw-alias-bg-layer-2)}.NPLLIq_switch:disabled{opacity:.5;cursor:default}.NPLLIq_notice,.NPLLIq_noticeError{color:var(--dsw-alias-label-secondary);padding:10px 12px;font-size:12px}.NPLLIq_noticeError{color:var(--dsw-alias-state-error-primary)}.NPLLIq_tab{background:var(--dsw-alias-brand-primary);border:1px solid var(--dsw-alias-brand-primary);color:var(--dsw-alias-bg-overlay);pointer-events:auto;cursor:pointer;z-index:90;border-radius:10px;align-items:center;gap:6px;padding:9px 14px;font-size:12px;font-weight:600;display:inline-flex;position:fixed;top:56px;right:12px;box-shadow:0 6px 20px #00000040}.NPLLIq_tab:hover{filter:brightness(1.08)}.NPLLIq_tabIcon{font-size:12px;line-height:1}.NPLLIq_tabLabel{white-space:nowrap}.NPLLIq_headerActions{flex:none;align-items:center;gap:4px;display:flex}.NPLLIq_settingsBtn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;padding:2px 6px;font-size:11px}.NPLLIq_settingsBtn:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_selectBtn{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-brand-primary);cursor:pointer;background:0 0;border-radius:6px;flex:none;padding:1px 6px;font-size:10px}.NPLLIq_selectBtn:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_gearBtn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;flex:none;margin-left:6px;padding:0 2px;font-size:12px;line-height:1}.NPLLIq_gearBtn:hover{color:var(--dsw-alias-label-primary)}.NPLLIq_fullNotice{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-state-error-primary);border-radius:8px;margin:6px 12px;padding:8px 10px;font-size:12px}.NPLLIq_upgradeBanner{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-divider-1,#0000001a);border-radius:8px;margin:6px 12px;padding:10px 30px 10px 10px;font-size:12px;position:relative}.NPLLIq_upgradeBannerText{margin-bottom:6px;font-weight:600}.NPLLIq_upgradeCommands{flex-direction:column;gap:4px;display:flex}.NPLLIq_upgradeCommandRow{align-items:center;gap:6px;display:flex}.NPLLIq_upgradeCommand{background:var(--dsw-alias-bg-layer-2,#0000000a);white-space:nowrap;border-radius:4px;flex:1;min-width:0;padding:4px 6px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;overflow-x:auto}.NPLLIq_copyBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;flex:none;padding:3px 8px;font-size:11px}.NPLLIq_copyBtn:hover{background:var(--dsw-alias-bg-layer-3,#00000014)}.NPLLIq_upgradeHint{color:var(--dsw-alias-label-secondary);margin-top:6px;font-size:11px}.NPLLIq_upgradeClose{width:20px;height:20px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;font-size:16px;line-height:1;position:absolute;top:4px;right:6px}.NPLLIq_upgradeClose:hover{background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary)}.NPLLIq_checkUpdatesRow{justify-content:space-between;align-items:center;gap:12px;display:flex}.NPLLIq_checkUpdatesLabel{color:var(--dsw-alias-label-primary);cursor:pointer;align-items:center;gap:6px;font-size:12px;display:flex}.NPLLIq_checkUpdatesLabel input{margin:0}.NPLLIq_checkBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;white-space:nowrap;text-align:center;border-radius:4px;flex:none;min-width:72px;padding:4px 10px;font-size:12px}.NPLLIq_checkBtn:hover:not(:disabled){background:var(--dsw-alias-bg-layer-3,#00000014)}.NPLLIq_checkBtn:disabled{opacity:.6;cursor:default}.NPLLIq_checkErrorHint{color:var(--dsw-alias-state-error-primary,#c00);background:var(--dsw-alias-state-error-background,#ff00000f);border:1px solid var(--dsw-alias-state-error-border,#b4000040);word-break:break-all;border-radius:6px;margin-top:8px;padding:6px 8px;font-size:11px;line-height:1.4}.NPLLIq_dialog{z-index:100;box-sizing:border-box;background:var(--dsw-alias-bg-overlay);border:1px solid var(--dsw-alias-border-l1);border-radius:12px;flex-direction:column;gap:12px;width:280px;max-height:80vh;padding:14px;display:flex;position:fixed;top:50%;left:50%;overflow-y:auto;transform:translate(-50%,-50%);box-shadow:0 8px 28px #00000040}.NPLLIq_dialogTitle{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.NPLLIq_dialogSection{flex-direction:column;gap:6px;display:flex}.NPLLIq_dialogLabel{color:var(--dsw-alias-label-primary);font-size:12px;font-weight:500}.NPLLIq_monitorHint{color:var(--dsw-alias-label-secondary);font-size:11px}.NPLLIq_monitorList{flex-direction:column;gap:2px;max-height:180px;display:flex;overflow-y:auto}.NPLLIq_monitorRow{color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:6px;padding:2px 4px;font-size:12px;display:flex}.NPLLIq_monitorRow:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_monitorName{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.NPLLIq_radioRow{color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:6px;padding:3px 4px;font-size:12px;display:flex}.NPLLIq_radioRow:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_dialogActions{justify-content:flex-end;gap:6px;display:flex}.NPLLIq_dialogBtn,.NPLLIq_dialogBtnPrimary{border:1px solid var(--dsw-alias-border-l1);cursor:pointer;border-radius:6px;padding:4px 12px;font-size:11px}.NPLLIq_dialogBtn{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)}.NPLLIq_dialogBtnPrimary{background:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-bg-overlay)}.NPLLIq_dialogHeader{z-index:2;background:var(--dsw-alias-bg-overlay);cursor:grab;user-select:none;touch-action:none;justify-content:space-between;align-items:center;gap:8px;margin:-14px -14px 0;padding:14px 14px 8px;display:flex;position:sticky;top:-14px}.NPLLIq_dialogHeader:active{cursor:grabbing}.NPLLIq_dialogClose{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:8px;flex:none;justify-content:center;align-items:center;font-size:18px;line-height:1;display:flex}.NPLLIq_dialogClose:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_resetRow{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.NPLLIq_resetSelect{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:6px;padding:3px 6px;font-size:12px}.NPLLIq_logTable{border-collapse:collapse;width:100%;font-size:11px}.NPLLIq_logTable th{text-align:left;color:var(--dsw-alias-label-secondary);border-bottom:1px solid var(--dsw-alias-border-l1);padding:4px 6px;font-weight:500}.NPLLIq_logTable td{color:var(--dsw-alias-label-primary);border-bottom:1px solid var(--dsw-alias-border-l1);font-variant-numeric:tabular-nums;padding:4px 6px}.NPLLIq_logDayCol{white-space:nowrap;color:var(--dsw-alias-label-secondary)}.NPLLIq_logModelCol{text-overflow:ellipsis;white-space:nowrap;max-width:160px;overflow:hidden}.NPLLIq_logUsedCol{text-align:right}.NPLLIq_logDialog{gap:0;width:380px;max-height:min(72vh,480px);padding:0}.NPLLIq_logHeader{background:var(--dsw-alias-bg-overlay);cursor:grab;user-select:none;touch-action:none;flex:none;justify-content:space-between;align-items:center;gap:8px;padding:14px 14px 8px;display:flex}.NPLLIq_logHeader:active{cursor:grabbing}.NPLLIq_logScroll{flex:1;min-height:0;padding:0 14px 14px;overflow:auto}.NPLLIq_logToolbar{flex:1;align-items:center;gap:6px;display:flex}.NPLLIq_logSearch{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);min-width:0;color:var(--dsw-alias-label-primary);border-radius:4px;flex:1;padding:3px 6px;font-size:11px}.NPLLIq_logSearch:focus{border-color:var(--dsw-alias-accent-1,#4a9eff);outline:none}.NPLLIq_logClearBtn{border:1px solid var(--dsw-alias-state-error-border,#b400004d);color:var(--dsw-alias-state-error-primary,#c00);cursor:pointer;white-space:nowrap;background:0 0;border-radius:4px;flex:none;padding:3px 8px;font-size:11px}.NPLLIq_logClearBtn:hover{background:var(--dsw-alias-state-error-background,#ff00000f)}.NPLLIq_logPager{border-top:1px solid var(--dsw-alias-divider-1,#00000014);background:var(--dsw-alias-bg-overlay);color:var(--dsw-alias-label-secondary);flex:none;justify-content:space-between;align-items:center;gap:8px;padding:6px 14px;font-size:11px;display:flex}.NPLLIq_logPagerInfo{white-space:nowrap}.NPLLIq_logPagerControls{align-items:center;gap:4px;display:flex}.NPLLIq_logPagerBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);width:24px;height:24px;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;font-size:13px;line-height:1}.NPLLIq_logPagerBtn:disabled{opacity:.4;cursor:default}.NPLLIq_logPagerPages{text-align:center;min-width:50px;color:var(--dsw-alias-label-secondary)}.NPLLIq_logPageSizeSelect{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;padding:2px 4px;font-size:11px}.NPLLIq_dialogOverlay{z-index:100001;background:#0000004d;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.NPLLIq_logClearDialog{gap:0;width:320px;padding:16px}.NPLLIq_dialogBody{color:var(--dsw-alias-label-secondary);margin:6px 0 10px;font-size:12px;line-height:1.5}.NPLLIq_logClearDate{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);width:100%;color:var(--dsw-alias-label-primary);border-radius:6px;margin-bottom:12px;padding:6px 8px;font-size:13px}.NPLLIq_logClearDate:focus{border-color:var(--dsw-alias-accent-1,#4a9eff);outline:none}";
170
174
  const tagId = "@jxgame2020/dsh-token-quota/TokenQuotaPanel.module.css";
171
175
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
172
176
  const tag = document.createElement("style");
@@ -176,85 +180,86 @@ window.__ModuleLoader__.load({
176
180
  document.head.appendChild(tag);
177
181
  }
178
182
  var TokenQuotaPanel_module_css_default = {
183
+ "logPager": "NPLLIq_logPager",
184
+ "checkUpdatesLabel": "NPLLIq_checkUpdatesLabel",
185
+ "dialogHeader": "NPLLIq_dialogHeader",
186
+ "resetRow": "NPLLIq_resetRow",
187
+ "logSearch": "NPLLIq_logSearch",
188
+ "upgradeHint": "NPLLIq_upgradeHint",
189
+ "settingsBtn": "NPLLIq_settingsBtn",
190
+ "monitorRow": "NPLLIq_monitorRow",
191
+ "dialogBody": "NPLLIq_dialogBody",
179
192
  "logHeader": "NPLLIq_logHeader",
180
- "title": "NPLLIq_title",
181
- "radioRow": "NPLLIq_radioRow",
182
- "logModelCol": "NPLLIq_logModelCol",
183
- "logPagerInfo": "NPLLIq_logPagerInfo",
184
- "upgradeClose": "NPLLIq_upgradeClose",
185
- "dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
186
- "subtitle": "NPLLIq_subtitle",
187
- "logPagerControls": "NPLLIq_logPagerControls",
188
- "dialogBtn": "NPLLIq_dialogBtn",
189
- "logPagerPages": "NPLLIq_logPagerPages",
190
- "headerActions": "NPLLIq_headerActions",
191
- "monitorHint": "NPLLIq_monitorHint",
192
- "dialogTitle": "NPLLIq_dialogTitle",
193
- "logDialog": "NPLLIq_logDialog",
193
+ "save": "NPLLIq_save",
194
+ "currentBadge": "NPLLIq_currentBadge",
195
+ "upgradeCommands": "NPLLIq_upgradeCommands",
196
+ "switch": "NPLLIq_switch",
197
+ "collapse": "NPLLIq_collapse",
198
+ "checkErrorHint": "NPLLIq_checkErrorHint",
194
199
  "header": "NPLLIq_header",
195
- "dialog": "NPLLIq_dialog",
196
- "tab": "NPLLIq_tab",
197
- "dialogHeader": "NPLLIq_dialogHeader",
198
- "logToolbar": "NPLLIq_logToolbar",
199
- "dialogLabel": "NPLLIq_dialogLabel",
200
- "logClearDate": "NPLLIq_logClearDate",
201
- "upgradeBanner": "NPLLIq_upgradeBanner",
202
- "bar": "NPLLIq_bar",
200
+ "input": "NPLLIq_input",
201
+ "upgradeBannerText": "NPLLIq_upgradeBannerText",
202
+ "fillOver": "NPLLIq_fillOver",
203
+ "title": "NPLLIq_title",
203
204
  "row": "NPLLIq_row",
205
+ "selectBtn": "NPLLIq_selectBtn",
204
206
  "copyBtn": "NPLLIq_copyBtn",
207
+ "checkBtn": "NPLLIq_checkBtn",
208
+ "dialogClose": "NPLLIq_dialogClose",
209
+ "logDayCol": "NPLLIq_logDayCol",
210
+ "upgradeBanner": "NPLLIq_upgradeBanner",
205
211
  "dialogActions": "NPLLIq_dialogActions",
212
+ "versionNew": "NPLLIq_versionNew",
213
+ "checkUpdatesRow": "NPLLIq_checkUpdatesRow",
214
+ "dialogLabel": "NPLLIq_dialogLabel",
215
+ "monitorHint": "NPLLIq_monitorHint",
216
+ "bar": "NPLLIq_bar",
217
+ "version": "NPLLIq_version",
218
+ "notice": "NPLLIq_notice",
219
+ "logToolbar": "NPLLIq_logToolbar",
206
220
  "logUsedCol": "NPLLIq_logUsedCol",
207
- "monitorRow": "NPLLIq_monitorRow",
208
- "tabLabel": "NPLLIq_tabLabel",
221
+ "logPagerControls": "NPLLIq_logPagerControls",
222
+ "dialog": "NPLLIq_dialog",
223
+ "logClearDialog": "NPLLIq_logClearDialog",
224
+ "rowHeader": "NPLLIq_rowHeader",
225
+ "fillWarn": "NPLLIq_fillWarn",
226
+ "noticeError": "NPLLIq_noticeError",
227
+ "logModelCol": "NPLLIq_logModelCol",
228
+ "logDialog": "NPLLIq_logDialog",
229
+ "rowMeta": "NPLLIq_rowMeta",
230
+ "logClearBtn": "NPLLIq_logClearBtn",
209
231
  "monitorName": "NPLLIq_monitorName",
210
- "logPageSizeSelect": "NPLLIq_logPageSizeSelect",
232
+ "logPagerBtn": "NPLLIq_logPagerBtn",
211
233
  "dialogSection": "NPLLIq_dialogSection",
212
- "save": "NPLLIq_save",
213
- "switch": "NPLLIq_switch",
214
- "upgradeCommandRow": "NPLLIq_upgradeCommandRow",
215
- "tabIcon": "NPLLIq_tabIcon",
216
- "version": "NPLLIq_version",
217
- "upgradeBannerText": "NPLLIq_upgradeBannerText",
234
+ "radioRow": "NPLLIq_radioRow",
235
+ "monitorList": "NPLLIq_monitorList",
236
+ "logPagerInfo": "NPLLIq_logPagerInfo",
218
237
  "panel": "NPLLIq_panel",
219
- "notice": "NPLLIq_notice",
220
- "fillOver": "NPLLIq_fillOver",
221
- "dialogOverlay": "NPLLIq_dialogOverlay",
222
- "fullNotice": "NPLLIq_fullNotice",
223
- "logDayCol": "NPLLIq_logDayCol",
224
- "rowHeader": "NPLLIq_rowHeader",
225
- "settingsBtn": "NPLLIq_settingsBtn",
238
+ "logTable": "NPLLIq_logTable",
239
+ "logPagerPages": "NPLLIq_logPagerPages",
226
240
  "gearBtn": "NPLLIq_gearBtn",
227
- "headerText": "NPLLIq_headerText",
228
- "collapse": "NPLLIq_collapse",
241
+ "dialogBtn": "NPLLIq_dialogBtn",
242
+ "controls": "NPLLIq_controls",
243
+ "logScroll": "NPLLIq_logScroll",
244
+ "upgradeClose": "NPLLIq_upgradeClose",
229
245
  "resetSelect": "NPLLIq_resetSelect",
230
- "upgradeCommands": "NPLLIq_upgradeCommands",
231
- "body": "NPLLIq_body",
246
+ "logPageSizeSelect": "NPLLIq_logPageSizeSelect",
232
247
  "rowName": "NPLLIq_rowName",
233
- "monitorList": "NPLLIq_monitorList",
234
- "logScroll": "NPLLIq_logScroll",
235
- "input": "NPLLIq_input",
236
- "resetRow": "NPLLIq_resetRow",
237
- "logPagerBtn": "NPLLIq_logPagerBtn",
238
- "logClearDialog": "NPLLIq_logClearDialog",
239
- "logTable": "NPLLIq_logTable",
240
- "upgradeHint": "NPLLIq_upgradeHint",
241
- "rowMeta": "NPLLIq_rowMeta",
248
+ "tabLabel": "NPLLIq_tabLabel",
249
+ "tab": "NPLLIq_tab",
242
250
  "fillIdle": "NPLLIq_fillIdle",
243
- "logClearBtn": "NPLLIq_logClearBtn",
244
- "logPager": "NPLLIq_logPager",
245
- "versionNew": "NPLLIq_versionNew",
246
- "dialogBody": "NPLLIq_dialogBody",
247
- "noticeError": "NPLLIq_noticeError",
248
- "checkUpdatesRow": "NPLLIq_checkUpdatesRow",
249
- "logSearch": "NPLLIq_logSearch",
250
- "checkBtn": "NPLLIq_checkBtn",
251
- "selectBtn": "NPLLIq_selectBtn",
251
+ "headerText": "NPLLIq_headerText",
252
+ "tabIcon": "NPLLIq_tabIcon",
253
+ "dialogTitle": "NPLLIq_dialogTitle",
254
+ "body": "NPLLIq_body",
255
+ "upgradeCommandRow": "NPLLIq_upgradeCommandRow",
256
+ "dialogOverlay": "NPLLIq_dialogOverlay",
257
+ "subtitle": "NPLLIq_subtitle",
258
+ "headerActions": "NPLLIq_headerActions",
252
259
  "upgradeCommand": "NPLLIq_upgradeCommand",
253
- "currentBadge": "NPLLIq_currentBadge",
254
- "controls": "NPLLIq_controls",
255
- "fillWarn": "NPLLIq_fillWarn",
256
- "dialogClose": "NPLLIq_dialogClose",
257
- "checkUpdatesLabel": "NPLLIq_checkUpdatesLabel"
260
+ "dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
261
+ "logClearDate": "NPLLIq_logClearDate",
262
+ "fullNotice": "NPLLIq_fullNotice"
258
263
  };
259
264
  //#endregion
260
265
  //#region lib/types/client/TokenQuotaPanel.js
@@ -368,6 +373,7 @@ window.__ModuleLoader__.load({
368
373
  const upgradeDismissed = useStore((s) => s.upgradeDismissed);
369
374
  const checkingUpdates = useStore((s) => s.checkingUpdates);
370
375
  const lastCheckResult = useStore((s) => s.lastCheckResult);
376
+ const upgradeError = useStore((s) => s.upgradeError);
371
377
  const reset = useStore((s) => s.reset);
372
378
  const dialogOpen = useStore((s) => s.dialogOpen);
373
379
  const logOpen = useStore((s) => s.logOpen);
@@ -500,13 +506,13 @@ window.__ModuleLoader__.load({
500
506
  title: t("upgradeAvailableHint"),
501
507
  children: [
502
508
  "v",
503
- "0.1.12",
509
+ "0.1.13",
504
510
  " → v",
505
511
  upgrade.latestVersion
506
512
  ]
507
513
  }) : (0, react_jsx_runtime.jsxs)("span", {
508
514
  className: TokenQuotaPanel_module_css_default.version,
509
- children: ["v", "0.1.12"]
515
+ children: ["v", "0.1.13"]
510
516
  })]
511
517
  }), (0, react_jsx_runtime.jsx)("div", {
512
518
  className: TokenQuotaPanel_module_css_default.subtitle,
@@ -827,9 +833,9 @@ window.__ModuleLoader__.load({
827
833
  })
828
834
  ]
829
835
  }),
830
- (0, react_jsx_runtime.jsx)("div", {
836
+ (0, react_jsx_runtime.jsxs)("div", {
831
837
  className: TokenQuotaPanel_module_css_default.dialogSection,
832
- children: (0, react_jsx_runtime.jsxs)("div", {
838
+ children: [(0, react_jsx_runtime.jsxs)("div", {
833
839
  className: TokenQuotaPanel_module_css_default.checkUpdatesRow,
834
840
  children: [(0, react_jsx_runtime.jsxs)("label", {
835
841
  className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
@@ -847,7 +853,11 @@ window.__ModuleLoader__.load({
847
853
  onClick: checkUpdatesNow,
848
854
  children: checkingUpdates ? t("checkingUpdates") : lastCheckResult === "up-to-date" ? t("checkUpToDate") : lastCheckResult === "error" ? t("checkFailed") : t("checkUpdatesNow")
849
855
  })]
850
- })
856
+ }), lastCheckResult === "error" && upgradeError !== null && (0, react_jsx_runtime.jsx)("div", {
857
+ className: TokenQuotaPanel_module_css_default.checkErrorHint,
858
+ role: "alert",
859
+ children: upgradeError
860
+ })]
851
861
  })
852
862
  ]
853
863
  }),
@@ -1322,6 +1332,7 @@ window.__ModuleLoader__.load({
1322
1332
  if (snapshot === void 0) return;
1323
1333
  bound?.setSnapshot(snapshot);
1324
1334
  bound?.setUpgrade(snapshot.upgrade ?? null);
1335
+ bound?.setUpgradeError(snapshot.upgradeError ?? null);
1325
1336
  actOnFull(snapshot);
1326
1337
  });
1327
1338
  if (pullCount % 2 === 0) refreshCurrent();
@@ -1391,13 +1402,14 @@ window.__ModuleLoader__.load({
1391
1402
  if (snapshot !== void 0) {
1392
1403
  bound?.setSnapshot(snapshot);
1393
1404
  bound?.setUpgrade(snapshot.upgrade ?? null);
1405
+ bound?.setUpgradeError(snapshot.upgradeError ?? null);
1394
1406
  actOnFull(snapshot);
1395
- if (snapshot.upgrade === null) bound?.setLastCheckResult("up-to-date");
1407
+ if (snapshot.upgrade === null) bound?.setLastCheckResult(snapshot.upgradeError !== null ? "error" : "up-to-date");
1396
1408
  }
1397
1409
  bound?.setCheckingUpdates(false);
1398
1410
  setTimeout(() => {
1399
1411
  bound?.setLastCheckResult("idle");
1400
- }, 2500);
1412
+ }, 4e3);
1401
1413
  });
1402
1414
  };
1403
1415
  const setReset = (reset) => {
package/lib/index.js CHANGED
@@ -225,6 +225,8 @@ var TokenQuotaService = class TokenQuotaService extends Service {
225
225
  checkUpdates = true;
226
226
  /** Cached upgrade availability; recomputed by {@link refreshUpgrade}. */
227
227
  upgrade = null;
228
+ /** Error message from the most recent update check; null = no error. */
229
+ upgradeError = null;
228
230
  /** Timer for the periodic update check. */
229
231
  updateTimer;
230
232
  /** In-flight update check, to coalesce the periodic and manual triggers. */
@@ -404,7 +406,7 @@ var TokenQuotaService = class TokenQuotaService extends Service {
404
406
  return this.upgradeCheck;
405
407
  }
406
408
  async doRefreshUpgrade() {
407
- const current = "0.1.12";
409
+ const current = "0.1.13";
408
410
  let latest;
409
411
  try {
410
412
  const response = await fetch(REGISTRY_LATEST_URL, {
@@ -413,16 +415,20 @@ var TokenQuotaService = class TokenQuotaService extends Service {
413
415
  });
414
416
  if (!response.ok) {
415
417
  this.upgrade = null;
418
+ this.upgradeError = `registry responded ${response.status} ${response.statusText}`;
416
419
  return;
417
420
  }
418
421
  const manifest = await response.json();
419
422
  latest = typeof manifest.version === "string" ? manifest.version : void 0;
420
- } catch {
423
+ } catch (err) {
421
424
  this.upgrade = null;
425
+ const msg = err instanceof Error ? err.message : String(err);
426
+ this.upgradeError = msg.includes("fetch failed") ? "无法访问 npm registry(网络超时或被墙)" : msg.includes("aborted") ? "请求超时(10s)" : msg;
422
427
  return;
423
428
  }
424
429
  if (latest === void 0 || !isNewer(latest, current)) {
425
430
  this.upgrade = null;
431
+ this.upgradeError = null;
426
432
  return;
427
433
  }
428
434
  const profile = findProfile();
@@ -432,6 +438,7 @@ var TokenQuotaService = class TokenQuotaService extends Service {
432
438
  commands,
433
439
  installKind: profile?.installKind ?? "registry"
434
440
  };
441
+ this.upgradeError = null;
435
442
  }
436
443
  /** Start or stop the periodic update check to match the current setting. */
437
444
  syncUpdateChecking() {
@@ -512,7 +519,8 @@ var TokenQuotaService = class TokenQuotaService extends Service {
512
519
  return {
513
520
  day: this.cycle,
514
521
  entries,
515
- upgrade: this.upgrade
522
+ upgrade: this.upgrade,
523
+ upgradeError: this.upgradeError
516
524
  };
517
525
  }
518
526
  /** Today's used tokens for one model key, or `0`. */
@@ -118,6 +118,7 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
118
118
  const upgradeDismissed = useStore(s => s.upgradeDismissed);
119
119
  const checkingUpdates = useStore(s => s.checkingUpdates);
120
120
  const lastCheckResult = useStore(s => s.lastCheckResult);
121
+ const upgradeError = useStore(s => s.upgradeError);
121
122
  const reset = useStore(s => s.reset);
122
123
  const dialogOpen = useStore(s => s.dialogOpen);
123
124
  const logOpen = useStore(s => s.logOpen);
@@ -261,13 +262,13 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
261
262
  hour: reset?.hour ?? 0,
262
263
  minute: Number(event.target.value),
263
264
  });
264
- }, children: Array.from({ length: 12 }, (_, i) => i * 5).map(minute => (_jsxs("option", { value: minute, children: [String(minute).padStart(2, '0'), " \u5206"] }, minute))) })] })] }), _jsx("div", { className: css.dialogSection, children: _jsxs("div", { className: css.checkUpdatesRow, children: [_jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("input", { type: "checkbox", checked: checkUpdates, onChange: (event) => { setCheckUpdates(event.target.checked); } }), _jsx("span", { children: t('checkUpdatesLabel') })] }), _jsx("button", { type: "button", className: css.checkBtn, disabled: checkingUpdates, onClick: checkUpdatesNow, children: checkingUpdates
265
- ? t('checkingUpdates')
266
- : lastCheckResult === 'up-to-date'
267
- ? t('checkUpToDate')
268
- : lastCheckResult === 'error'
269
- ? t('checkFailed')
270
- : t('checkUpdatesNow') })] }) })] })), logOpen && (_jsxs("div", { ref: logRef, className: `${css.dialog} ${css.logDialog}`, style: logPos !== null ? { left: logPos.x, top: logPos.y, transform: 'none' } : undefined, children: [_jsxs("div", { className: css.logHeader, onPointerDown: (event) => { beginDrag(event, logRef.current, setLogPos); }, children: [_jsx("div", { className: css.dialogTitle, children: t('logsTitle') }), _jsxs("div", { className: css.logToolbar, onPointerDown: (event) => { event.stopPropagation(); }, children: [_jsx("input", { type: "search", className: css.logSearch, placeholder: t('logSearchPlaceholder'), value: logSearch, onChange: (event) => { actions.setLogSearch(event.target.value); } }), _jsx("button", { type: "button", className: css.logClearBtn, onClick: () => { actions.setLogClearOpen(true); }, children: t('logClear') })] }), _jsx("button", { type: "button", className: css.dialogClose, title: t('close'), onClick: () => { actions.setLogOpen(false); }, children: "\u00D7" })] }), log !== null && filteredLogEntries.length === 0 && (_jsx("div", { className: css.notice, children: logSearch.trim() !== '' ? t('logNoMatch') : t('logEmpty') })), _jsx("div", { className: css.logScroll, children: _jsxs("table", { className: css.logTable, children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: t('logDay') }), _jsx("th", { children: t('logModel') }), _jsx("th", { className: css.logUsedCol, children: t('logUsed') })] }) }), _jsx("tbody", { children: logPageEntries.map(entry => (_jsxs("tr", { children: [_jsx("td", { className: css.logDayCol, children: entry.day }), _jsx("td", { className: css.logModelCol, title: entry.key, children: entry.key }), _jsx("td", { className: css.logUsedCol, children: formatTokens(entry.used) })] }, `${entry.day}/${entry.key}`))) })] }) }), _jsxs("div", { className: css.logPager, children: [_jsx("span", { className: css.logPagerInfo, children: t('logPagerInfo')
265
+ }, children: Array.from({ length: 12 }, (_, i) => i * 5).map(minute => (_jsxs("option", { value: minute, children: [String(minute).padStart(2, '0'), " \u5206"] }, minute))) })] })] }), _jsxs("div", { className: css.dialogSection, children: [_jsxs("div", { className: css.checkUpdatesRow, children: [_jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("input", { type: "checkbox", checked: checkUpdates, onChange: (event) => { setCheckUpdates(event.target.checked); } }), _jsx("span", { children: t('checkUpdatesLabel') })] }), _jsx("button", { type: "button", className: css.checkBtn, disabled: checkingUpdates, onClick: checkUpdatesNow, children: checkingUpdates
266
+ ? t('checkingUpdates')
267
+ : lastCheckResult === 'up-to-date'
268
+ ? t('checkUpToDate')
269
+ : lastCheckResult === 'error'
270
+ ? t('checkFailed')
271
+ : t('checkUpdatesNow') })] }), lastCheckResult === 'error' && upgradeError !== null && (_jsx("div", { className: css.checkErrorHint, role: "alert", children: upgradeError }))] })] })), logOpen && (_jsxs("div", { ref: logRef, className: `${css.dialog} ${css.logDialog}`, style: logPos !== null ? { left: logPos.x, top: logPos.y, transform: 'none' } : undefined, children: [_jsxs("div", { className: css.logHeader, onPointerDown: (event) => { beginDrag(event, logRef.current, setLogPos); }, children: [_jsx("div", { className: css.dialogTitle, children: t('logsTitle') }), _jsxs("div", { className: css.logToolbar, onPointerDown: (event) => { event.stopPropagation(); }, children: [_jsx("input", { type: "search", className: css.logSearch, placeholder: t('logSearchPlaceholder'), value: logSearch, onChange: (event) => { actions.setLogSearch(event.target.value); } }), _jsx("button", { type: "button", className: css.logClearBtn, onClick: () => { actions.setLogClearOpen(true); }, children: t('logClear') })] }), _jsx("button", { type: "button", className: css.dialogClose, title: t('close'), onClick: () => { actions.setLogOpen(false); }, children: "\u00D7" })] }), log !== null && filteredLogEntries.length === 0 && (_jsx("div", { className: css.notice, children: logSearch.trim() !== '' ? t('logNoMatch') : t('logEmpty') })), _jsx("div", { className: css.logScroll, children: _jsxs("table", { className: css.logTable, children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: t('logDay') }), _jsx("th", { children: t('logModel') }), _jsx("th", { className: css.logUsedCol, children: t('logUsed') })] }) }), _jsx("tbody", { children: logPageEntries.map(entry => (_jsxs("tr", { children: [_jsx("td", { className: css.logDayCol, children: entry.day }), _jsx("td", { className: css.logModelCol, title: entry.key, children: entry.key }), _jsx("td", { className: css.logUsedCol, children: formatTokens(entry.used) })] }, `${entry.day}/${entry.key}`))) })] }) }), _jsxs("div", { className: css.logPager, children: [_jsx("span", { className: css.logPagerInfo, children: t('logPagerInfo')
271
272
  .replace('{from}', String(logCurrentPage * logPageSize + 1))
272
273
  .replace('{to}', String(Math.min((logCurrentPage + 1) * logPageSize, filteredLogEntries.length)))
273
274
  .replace('{total}', String(filteredLogEntries.length)) }), _jsxs("div", { className: css.logPagerControls, children: [_jsx("button", { type: "button", className: css.logPagerBtn, disabled: logCurrentPage <= 0, onClick: () => { actions.setLogPage(logCurrentPage - 1); }, children: "\u2039" }), _jsxs("span", { className: css.logPagerPages, children: [logCurrentPage + 1, " / ", logTotalPages] }), _jsx("button", { type: "button", className: css.logPagerBtn, disabled: logCurrentPage >= logTotalPages - 1, onClick: () => { actions.setLogPage(logCurrentPage + 1); }, children: "\u203A" }), _jsx("select", { className: css.logPageSizeSelect, value: logPageSize, onChange: (event) => { actions.setLogPageSize(Number(event.target.value)); }, children: [10, 15, 20, 50, 100].map(size => (_jsxs("option", { value: size, children: [size, t('logPerPage')] }, size))) })] })] })] })), logClearOpen && (_jsx("div", { className: css.dialogOverlay, children: _jsxs("div", { className: `${css.dialog} ${css.logClearDialog}`, children: [_jsx("div", { className: css.dialogTitle, children: t('logClearTitle') }), _jsx("div", { className: css.dialogBody, children: t('logClearHint') }), _jsx("input", { type: "date", className: css.logClearDate, value: logClearBefore, onChange: (event) => { actions.setLogClearBefore(event.target.value); } }), _jsxs("div", { className: css.dialogActions, children: [_jsx("button", { type: "button", className: css.checkBtn, disabled: logClearBefore === '' || logClearing, onClick: () => { clearLogBefore(logClearBefore); }, children: logClearing ? t('logClearing') : t('logClearConfirm') }), _jsx("button", { type: "button", className: css.checkBtn, onClick: () => { actions.setLogClearOpen(false); }, children: t('logClearCancel') })] })] }) }))] }));
@@ -185,6 +185,7 @@ export function apply(ctx) {
185
185
  return;
186
186
  bound?.setSnapshot(snapshot);
187
187
  bound?.setUpgrade(snapshot.upgrade ?? null);
188
+ bound?.setUpgradeError(snapshot.upgradeError ?? null);
188
189
  actOnFull(snapshot);
189
190
  });
190
191
  if (pullCount % 2 === 0)
@@ -251,15 +252,18 @@ export function apply(ctx) {
251
252
  if (snapshot !== undefined) {
252
253
  bound?.setSnapshot(snapshot);
253
254
  bound?.setUpgrade(snapshot.upgrade ?? null);
255
+ bound?.setUpgradeError(snapshot.upgradeError ?? null);
254
256
  actOnFull(snapshot);
255
257
  if (snapshot.upgrade === null) {
256
- bound?.setLastCheckResult('up-to-date');
258
+ // No newer version known: distinguish "checked OK, up to date"
259
+ // from "check failed" via the host-provided error message.
260
+ bound?.setLastCheckResult(snapshot.upgradeError !== null ? 'error' : 'up-to-date');
257
261
  }
258
262
  }
259
263
  bound?.setCheckingUpdates(false);
260
264
  // Clear the transient result hint after a short delay so the button
261
- // returns to its idle label.
262
- setTimeout(() => { bound?.setLastCheckResult('idle'); }, 2500);
265
+ // returns to its idle label. The error message stays until the next check.
266
+ setTimeout(() => { bound?.setLastCheckResult('idle'); }, 4000);
263
267
  });
264
268
  };
265
269
  const setReset = (reset) => {
@@ -56,6 +56,8 @@ export interface TokenQuotaPanelState {
56
56
  checkingUpdates: boolean;
57
57
  /** Result of the most recent manual check; 'idle' = nothing to show. */
58
58
  lastCheckResult: 'idle' | 'up-to-date' | 'error';
59
+ /** Error message from the most recent update check (shown when lastCheckResult='error'). */
60
+ upgradeError: string | null;
59
61
  /** Whether the settings dialog is open. */
60
62
  dialogOpen: boolean;
61
63
  /** Full-quota notice shown for the `'stop'` strategy; null when none. */
@@ -91,6 +93,7 @@ export type TokenQuotaPanelActions = {
91
93
  setUpgradeDismissed: (d: TokenQuotaPanelState, dismissed: boolean) => void;
92
94
  setCheckingUpdates: (d: TokenQuotaPanelState, checking: boolean) => void;
93
95
  setLastCheckResult: (d: TokenQuotaPanelState, result: 'idle' | 'up-to-date' | 'error') => void;
96
+ setUpgradeError: (d: TokenQuotaPanelState, error: string | null) => void;
94
97
  setDialogOpen: (d: TokenQuotaPanelState, open: boolean) => void;
95
98
  setFullNotice: (d: TokenQuotaPanelState, notice: string | null) => void;
96
99
  setReset: (d: TokenQuotaPanelState, reset: TokenQuotaReset | null) => void;
@@ -31,6 +31,7 @@ export function createTokenQuotaPanelStore() {
31
31
  upgradeDismissed: false,
32
32
  checkingUpdates: false,
33
33
  lastCheckResult: 'idle',
34
+ upgradeError: null,
34
35
  dialogOpen: false,
35
36
  fullNotice: null,
36
37
  reset: null,
@@ -61,6 +62,7 @@ export function createTokenQuotaPanelStore() {
61
62
  setUpgradeDismissed: (d, dismissed) => { d.upgradeDismissed = dismissed; },
62
63
  setCheckingUpdates: (d, checking) => { d.checkingUpdates = checking; },
63
64
  setLastCheckResult: (d, result) => { d.lastCheckResult = result; },
65
+ setUpgradeError: (d, error) => { d.upgradeError = error; },
64
66
  setDialogOpen: (d, open) => { d.dialogOpen = open; },
65
67
  setFullNotice: (d, notice) => { d.fullNotice = notice; },
66
68
  setReset: (d, reset) => { d.reset = reset; },
@@ -59,6 +59,8 @@ export declare class TokenQuotaService extends Service {
59
59
  private checkUpdates;
60
60
  /** Cached upgrade availability; recomputed by {@link refreshUpgrade}. */
61
61
  private upgrade;
62
+ /** Error message from the most recent update check; null = no error. */
63
+ private upgradeError;
62
64
  /** Timer for the periodic update check. */
63
65
  private updateTimer;
64
66
  /** In-flight update check, to coalesce the periodic and manual triggers. */
@@ -225,6 +225,8 @@ export class TokenQuotaService extends Service {
225
225
  checkUpdates = true;
226
226
  /** Cached upgrade availability; recomputed by {@link refreshUpgrade}. */
227
227
  upgrade = null;
228
+ /** Error message from the most recent update check; null = no error. */
229
+ upgradeError = null;
228
230
  /** Timer for the periodic update check. */
229
231
  updateTimer;
230
232
  /** In-flight update check, to coalesce the periodic and manual triggers. */
@@ -427,6 +429,7 @@ export class TokenQuotaService extends Service {
427
429
  const current = __TOKEN_QUOTA_VERSION__;
428
430
  if (current === undefined || current === '') {
429
431
  this.upgrade = null;
432
+ this.upgradeError = null;
430
433
  return;
431
434
  }
432
435
  let latest;
@@ -437,18 +440,26 @@ export class TokenQuotaService extends Service {
437
440
  });
438
441
  if (!response.ok) {
439
442
  this.upgrade = null;
443
+ this.upgradeError = `registry responded ${response.status} ${response.statusText}`;
440
444
  return;
441
445
  }
442
446
  const manifest = await response.json();
443
447
  latest = typeof manifest.version === 'string' ? manifest.version : undefined;
444
448
  }
445
- catch {
446
- // Offline / registry failure: keep showing nothing rather than erroring.
449
+ catch (err) {
447
450
  this.upgrade = null;
451
+ const msg = err instanceof Error ? err.message : String(err);
452
+ // Common Node fetch error shapes include the URL; surface a short reason.
453
+ this.upgradeError = msg.includes('fetch failed')
454
+ ? '无法访问 npm registry(网络超时或被墙)'
455
+ : msg.includes('aborted')
456
+ ? '请求超时(10s)'
457
+ : msg;
448
458
  return;
449
459
  }
450
460
  if (latest === undefined || !isNewer(latest, current)) {
451
461
  this.upgrade = null;
462
+ this.upgradeError = null;
452
463
  return;
453
464
  }
454
465
  const profile = findProfile();
@@ -462,6 +473,7 @@ export class TokenQuotaService extends Service {
462
473
  commands,
463
474
  installKind: profile?.installKind ?? 'registry',
464
475
  };
476
+ this.upgradeError = null;
465
477
  }
466
478
  /** Start or stop the periodic update check to match the current setting. */
467
479
  syncUpdateChecking() {
@@ -540,7 +552,7 @@ export class TokenQuotaService extends Service {
540
552
  });
541
553
  }
542
554
  entries.sort((left, right) => left.key.localeCompare(right.key));
543
- return { day: this.cycle, entries, upgrade: this.upgrade };
555
+ return { day: this.cycle, entries, upgrade: this.upgrade, upgradeError: this.upgradeError };
544
556
  }
545
557
  /** Today's used tokens for one model key, or `0`. */
546
558
  usedToday(key) {
@@ -125,6 +125,8 @@ export interface TokenQuotaSnapshot {
125
125
  entries: TokenQuotaEntry[];
126
126
  /** Upgrade availability; `null` when no newer version is known. */
127
127
  upgrade: TokenQuotaUpgrade | null;
128
+ /** Error from the most recent update check; `null` = no error (or never checked). */
129
+ upgradeError: string | null;
128
130
  }
129
131
  /** One historical daily usage record, shown in the log dialog. */
130
132
  export interface TokenQuotaLogEntry {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jxgame2020/dsh-token-quota",
3
3
  "description": "Daily per-model token quota accounting, enforcement, and a floating quota panel for the DeepSeek Harness — a fully self-contained plugin (no core-Harness wiring, no generated RPC contract)",
4
- "version": "0.1.12",
4
+ "version": "0.1.13",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },