@jxgame2020/dsh-token-quota 0.1.16 → 0.1.18
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 +108 -75
- package/lib/index.js +58 -10
- package/lib/types/client/TokenQuotaPanel.d.ts +3 -1
- package/lib/types/client/TokenQuotaPanel.js +9 -8
- package/lib/types/client/index.js +6 -1
- package/lib/types/client/locales.d.ts +4 -0
- package/lib/types/client/locales.js +4 -0
- package/lib/types/client/store.d.ts +3 -0
- package/lib/types/client/store.js +13 -2
- package/lib/types/index.js +61 -13
- package/lib/types/types.d.ts +6 -0
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -36,6 +36,7 @@ window.__ModuleLoader__.load({
|
|
|
36
36
|
monitored: null,
|
|
37
37
|
onFull: "stop",
|
|
38
38
|
checkUpdates: true,
|
|
39
|
+
dimWhenIdle: false,
|
|
39
40
|
upgrade: null,
|
|
40
41
|
upgradeDismissed: false,
|
|
41
42
|
checkingUpdates: false,
|
|
@@ -74,9 +75,13 @@ window.__ModuleLoader__.load({
|
|
|
74
75
|
setCheckUpdates: (d, checkUpdates) => {
|
|
75
76
|
d.checkUpdates = checkUpdates;
|
|
76
77
|
},
|
|
78
|
+
setDimWhenIdle: (d, dimWhenIdle) => {
|
|
79
|
+
d.dimWhenIdle = dimWhenIdle;
|
|
80
|
+
},
|
|
77
81
|
setUpgrade: (d, upgrade) => {
|
|
78
|
-
|
|
79
|
-
d.upgrade =
|
|
82
|
+
const normalized = upgrade !== null && upgrade.latestVersion !== "" && upgrade.latestVersion !== "0.1.18" ? upgrade : null;
|
|
83
|
+
if (d.upgrade === null || d.upgrade.latestVersion !== normalized?.latestVersion) d.upgradeDismissed = false;
|
|
84
|
+
d.upgrade = normalized;
|
|
80
85
|
},
|
|
81
86
|
setUpgradeDismissed: (d, dismissed) => {
|
|
82
87
|
d.upgradeDismissed = dismissed;
|
|
@@ -170,7 +175,7 @@ window.__ModuleLoader__.load({
|
|
|
170
175
|
}
|
|
171
176
|
//#endregion
|
|
172
177
|
//#region \0dsh-css:/Users/jxgame/Desktop/works/deepseek-harness-package/dsh-token-quota/packages/token-quota/src/client/TokenQuotaPanel.module.css.mjs
|
|
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;opacity:1;border-radius:12px;flex-direction:column;width:320px;max-height:min(72vh,560px);transition:opacity .18s;display:flex;position:fixed;top:56px;right:12px;overflow:hidden;box-shadow:0 8px 28px #0000002e}.NPLLIq_panelDim{opacity:.55}.NPLLIq_panelDimStrong{opacity:.3}.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}@keyframes NPLLIq_upgradeBannerFlash{0%,to{border-color:var(--dsw-alias-divider-1,#0000001a);box-shadow:0 0 #f0a02000}50%{border-color:var(--dsw-alias-status-warning-foreground,#b56900);box-shadow:0 0 0 5px #f0a02073}}.NPLLIq_upgradeBannerFlash{border-color:var(--dsw-alias-status-warning-foreground,#b56900);animation:.6s ease-in-out 4 NPLLIq_upgradeBannerFlash}.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;transition:transform 80ms,background .12s,color .12s}.NPLLIq_copyBtn:hover{background:var(--dsw-alias-bg-layer-3,#00000014)}.NPLLIq_copyBtn:active{transform:scale(.92)}.NPLLIq_copyBtnDone{background:var(--dsw-alias-status-success-background,#14963c1f);border-color:var(--dsw-alias-status-success-foreground,#0a7d32);color:var(--dsw-alias-status-success-foreground,#0a7d32);font-weight:600}.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}";
|
|
178
|
+
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;opacity:1;border-radius:12px;flex-direction:column;width:320px;max-height:min(72vh,560px);transition:opacity .18s;display:flex;position:fixed;top:56px;right:12px;overflow:hidden;box-shadow:0 8px 28px #0000002e}.NPLLIq_panelDim{opacity:.55}.NPLLIq_panelDimStrong{opacity:.3}.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}@keyframes NPLLIq_upgradeBannerFlash{0%,to{border-color:var(--dsw-alias-divider-1,#0000001a);box-shadow:0 0 #f0a02000}50%{border-color:var(--dsw-alias-status-warning-foreground,#b56900);box-shadow:0 0 0 5px #f0a02073}}.NPLLIq_upgradeBannerFlash{border-color:var(--dsw-alias-status-warning-foreground,#b56900);animation:.6s ease-in-out 4 NPLLIq_upgradeBannerFlash}.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;transition:transform 80ms,background .12s,color .12s}.NPLLIq_copyBtn:hover{background:var(--dsw-alias-bg-layer-3,#00000014)}.NPLLIq_copyBtn:active{transform:scale(.92)}.NPLLIq_copyBtnDone{background:var(--dsw-alias-status-success-background,#14963c1f);border-color:var(--dsw-alias-status-success-foreground,#0a7d32);color:var(--dsw-alias-status-success-foreground,#0a7d32);font-weight:600}.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_dialogHint{color:var(--dsw-alias-label-secondary);margin-top:4px;font-size:11px;line-height:1.4}.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}";
|
|
174
179
|
const tagId = "@jxgame2020/dsh-token-quota/TokenQuotaPanel.module.css";
|
|
175
180
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
176
181
|
const tag = document.createElement("style");
|
|
@@ -180,90 +185,91 @@ window.__ModuleLoader__.load({
|
|
|
180
185
|
document.head.appendChild(tag);
|
|
181
186
|
}
|
|
182
187
|
var TokenQuotaPanel_module_css_default = {
|
|
183
|
-
"
|
|
184
|
-
"
|
|
188
|
+
"tabIcon": "NPLLIq_tabIcon",
|
|
189
|
+
"upgradeCommands": "NPLLIq_upgradeCommands",
|
|
185
190
|
"versionNew": "NPLLIq_versionNew",
|
|
186
|
-
"
|
|
187
|
-
"
|
|
188
|
-
"
|
|
189
|
-
"
|
|
190
|
-
"
|
|
191
|
+
"checkErrorHint": "NPLLIq_checkErrorHint",
|
|
192
|
+
"collapse": "NPLLIq_collapse",
|
|
193
|
+
"rowName": "NPLLIq_rowName",
|
|
194
|
+
"upgradeBannerFlash": "NPLLIq_upgradeBannerFlash",
|
|
195
|
+
"dialogHint": "NPLLIq_dialogHint",
|
|
196
|
+
"panelDim": "NPLLIq_panelDim",
|
|
191
197
|
"upgradeHint": "NPLLIq_upgradeHint",
|
|
192
|
-
"dialogHeader": "NPLLIq_dialogHeader",
|
|
193
|
-
"save": "NPLLIq_save",
|
|
194
|
-
"fillOver": "NPLLIq_fillOver",
|
|
195
|
-
"body": "NPLLIq_body",
|
|
196
|
-
"dialogActions": "NPLLIq_dialogActions",
|
|
197
|
-
"logClearBtn": "NPLLIq_logClearBtn",
|
|
198
|
-
"row": "NPLLIq_row",
|
|
199
|
-
"input": "NPLLIq_input",
|
|
200
198
|
"logPagerInfo": "NPLLIq_logPagerInfo",
|
|
199
|
+
"resetSelect": "NPLLIq_resetSelect",
|
|
201
200
|
"logClearDialog": "NPLLIq_logClearDialog",
|
|
202
|
-
"
|
|
203
|
-
"dialog": "NPLLIq_dialog",
|
|
204
|
-
"logHeader": "NPLLIq_logHeader",
|
|
205
|
-
"collapse": "NPLLIq_collapse",
|
|
201
|
+
"dialogClose": "NPLLIq_dialogClose",
|
|
206
202
|
"selectBtn": "NPLLIq_selectBtn",
|
|
207
|
-
"
|
|
203
|
+
"logClearDate": "NPLLIq_logClearDate",
|
|
204
|
+
"rowMeta": "NPLLIq_rowMeta",
|
|
205
|
+
"tabLabel": "NPLLIq_tabLabel",
|
|
206
|
+
"dialogSection": "NPLLIq_dialogSection",
|
|
208
207
|
"copyBtn": "NPLLIq_copyBtn",
|
|
209
|
-
"
|
|
210
|
-
"
|
|
211
|
-
"
|
|
208
|
+
"resetRow": "NPLLIq_resetRow",
|
|
209
|
+
"dialogActions": "NPLLIq_dialogActions",
|
|
210
|
+
"fillOver": "NPLLIq_fillOver",
|
|
211
|
+
"save": "NPLLIq_save",
|
|
212
|
+
"logModelCol": "NPLLIq_logModelCol",
|
|
213
|
+
"fillIdle": "NPLLIq_fillIdle",
|
|
212
214
|
"header": "NPLLIq_header",
|
|
213
|
-
"
|
|
214
|
-
"logPagerPages": "NPLLIq_logPagerPages",
|
|
215
|
-
"logPageSizeSelect": "NPLLIq_logPageSizeSelect",
|
|
216
|
-
"version": "NPLLIq_version",
|
|
217
|
-
"rowHeader": "NPLLIq_rowHeader",
|
|
218
|
-
"controls": "NPLLIq_controls",
|
|
219
|
-
"monitorRow": "NPLLIq_monitorRow",
|
|
220
|
-
"tab": "NPLLIq_tab",
|
|
221
|
-
"logDayCol": "NPLLIq_logDayCol",
|
|
222
|
-
"logScroll": "NPLLIq_logScroll",
|
|
215
|
+
"logUsedCol": "NPLLIq_logUsedCol",
|
|
223
216
|
"radioRow": "NPLLIq_radioRow",
|
|
224
|
-
"
|
|
225
|
-
"
|
|
226
|
-
"
|
|
217
|
+
"dialogBtn": "NPLLIq_dialogBtn",
|
|
218
|
+
"body": "NPLLIq_body",
|
|
219
|
+
"monitorName": "NPLLIq_monitorName",
|
|
220
|
+
"dialog": "NPLLIq_dialog",
|
|
221
|
+
"switch": "NPLLIq_switch",
|
|
222
|
+
"currentBadge": "NPLLIq_currentBadge",
|
|
223
|
+
"subtitle": "NPLLIq_subtitle",
|
|
224
|
+
"upgradeBanner": "NPLLIq_upgradeBanner",
|
|
225
|
+
"copyBtnDone": "NPLLIq_copyBtnDone",
|
|
226
|
+
"checkUpdatesRow": "NPLLIq_checkUpdatesRow",
|
|
227
|
+
"logScroll": "NPLLIq_logScroll",
|
|
228
|
+
"logToolbar": "NPLLIq_logToolbar",
|
|
227
229
|
"logPagerControls": "NPLLIq_logPagerControls",
|
|
230
|
+
"logPageSizeSelect": "NPLLIq_logPageSizeSelect",
|
|
231
|
+
"logDialog": "NPLLIq_logDialog",
|
|
232
|
+
"logDayCol": "NPLLIq_logDayCol",
|
|
228
233
|
"monitorList": "NPLLIq_monitorList",
|
|
234
|
+
"panelDimStrong": "NPLLIq_panelDimStrong",
|
|
235
|
+
"monitorHint": "NPLLIq_monitorHint",
|
|
229
236
|
"logTable": "NPLLIq_logTable",
|
|
230
|
-
"
|
|
231
|
-
"
|
|
232
|
-
"
|
|
233
|
-
"
|
|
234
|
-
"
|
|
237
|
+
"logPager": "NPLLIq_logPager",
|
|
238
|
+
"dialogOverlay": "NPLLIq_dialogOverlay",
|
|
239
|
+
"noticeError": "NPLLIq_noticeError",
|
|
240
|
+
"tab": "NPLLIq_tab",
|
|
241
|
+
"upgradeBannerText": "NPLLIq_upgradeBannerText",
|
|
242
|
+
"logClearBtn": "NPLLIq_logClearBtn",
|
|
235
243
|
"notice": "NPLLIq_notice",
|
|
244
|
+
"fillWarn": "NPLLIq_fillWarn",
|
|
245
|
+
"upgradeCommand": "NPLLIq_upgradeCommand",
|
|
246
|
+
"dialogHeader": "NPLLIq_dialogHeader",
|
|
247
|
+
"title": "NPLLIq_title",
|
|
248
|
+
"logSearch": "NPLLIq_logSearch",
|
|
249
|
+
"controls": "NPLLIq_controls",
|
|
250
|
+
"input": "NPLLIq_input",
|
|
251
|
+
"logHeader": "NPLLIq_logHeader",
|
|
252
|
+
"settingsBtn": "NPLLIq_settingsBtn",
|
|
253
|
+
"upgradeCommandRow": "NPLLIq_upgradeCommandRow",
|
|
254
|
+
"dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
|
|
236
255
|
"logPagerBtn": "NPLLIq_logPagerBtn",
|
|
256
|
+
"panel": "NPLLIq_panel",
|
|
257
|
+
"version": "NPLLIq_version",
|
|
258
|
+
"upgradeClose": "NPLLIq_upgradeClose",
|
|
259
|
+
"headerText": "NPLLIq_headerText",
|
|
260
|
+
"fullNotice": "NPLLIq_fullNotice",
|
|
261
|
+
"logPagerPages": "NPLLIq_logPagerPages",
|
|
237
262
|
"headerActions": "NPLLIq_headerActions",
|
|
238
|
-
"
|
|
239
|
-
"
|
|
240
|
-
"
|
|
241
|
-
"panelDimStrong": "NPLLIq_panelDimStrong",
|
|
242
|
-
"noticeError": "NPLLIq_noticeError",
|
|
243
|
-
"monitorName": "NPLLIq_monitorName",
|
|
244
|
-
"switch": "NPLLIq_switch",
|
|
245
|
-
"settingsBtn": "NPLLIq_settingsBtn",
|
|
246
|
-
"rowName": "NPLLIq_rowName",
|
|
263
|
+
"rowHeader": "NPLLIq_rowHeader",
|
|
264
|
+
"bar": "NPLLIq_bar",
|
|
265
|
+
"dialogTitle": "NPLLIq_dialogTitle",
|
|
247
266
|
"checkUpdatesLabel": "NPLLIq_checkUpdatesLabel",
|
|
248
|
-
"dialogClose": "NPLLIq_dialogClose",
|
|
249
|
-
"logUsedCol": "NPLLIq_logUsedCol",
|
|
250
|
-
"dialogOverlay": "NPLLIq_dialogOverlay",
|
|
251
267
|
"gearBtn": "NPLLIq_gearBtn",
|
|
252
|
-
"
|
|
253
|
-
"
|
|
254
|
-
"upgradeClose": "NPLLIq_upgradeClose",
|
|
255
|
-
"checkUpdatesRow": "NPLLIq_checkUpdatesRow",
|
|
256
|
-
"currentBadge": "NPLLIq_currentBadge",
|
|
257
|
-
"logToolbar": "NPLLIq_logToolbar",
|
|
258
|
-
"bar": "NPLLIq_bar",
|
|
268
|
+
"monitorRow": "NPLLIq_monitorRow",
|
|
269
|
+
"checkBtn": "NPLLIq_checkBtn",
|
|
259
270
|
"dialogLabel": "NPLLIq_dialogLabel",
|
|
260
|
-
"
|
|
261
|
-
"
|
|
262
|
-
"upgradeCommands": "NPLLIq_upgradeCommands",
|
|
263
|
-
"copyBtnDone": "NPLLIq_copyBtnDone",
|
|
264
|
-
"logModelCol": "NPLLIq_logModelCol",
|
|
265
|
-
"tabLabel": "NPLLIq_tabLabel",
|
|
266
|
-
"logDialog": "NPLLIq_logDialog"
|
|
271
|
+
"dialogBody": "NPLLIq_dialogBody",
|
|
272
|
+
"row": "NPLLIq_row"
|
|
267
273
|
};
|
|
268
274
|
//#endregion
|
|
269
275
|
//#region lib/types/client/TokenQuotaPanel.js
|
|
@@ -350,7 +356,7 @@ window.__ModuleLoader__.load({
|
|
|
350
356
|
* @param props - composed slot props.
|
|
351
357
|
* @returns the panel element tree.
|
|
352
358
|
*/
|
|
353
|
-
function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, useStore, actions, useSessions }) {
|
|
359
|
+
function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, setDimWhenIdle, useStore, actions, useSessions }) {
|
|
354
360
|
const [collapsed, setCollapsed] = (0, react.useState)(false);
|
|
355
361
|
const [drafts, setDrafts] = (0, react.useState)({});
|
|
356
362
|
const [editingKey, setEditingKey] = (0, react.useState)(null);
|
|
@@ -380,6 +386,7 @@ window.__ModuleLoader__.load({
|
|
|
380
386
|
const monitored = useStore((s) => s.monitored);
|
|
381
387
|
const onFull = useStore((s) => s.onFull);
|
|
382
388
|
const checkUpdates = useStore((s) => s.checkUpdates);
|
|
389
|
+
const dimWhenIdle = useStore((s) => s.dimWhenIdle);
|
|
383
390
|
const upgrade = useStore((s) => s.upgrade);
|
|
384
391
|
const upgradeDismissed = useStore((s) => s.upgradeDismissed);
|
|
385
392
|
const checkingUpdates = useStore((s) => s.checkingUpdates);
|
|
@@ -535,7 +542,7 @@ window.__ModuleLoader__.load({
|
|
|
535
542
|
setLimit(row.key, parsed);
|
|
536
543
|
};
|
|
537
544
|
const visibleRows = rows.filter((row) => isMonitoredKey(row.key) || row.current);
|
|
538
|
-
const panelDimClass = hovered || upgradeFlash ? "" : inputActive ? TokenQuotaPanel_module_css_default.panelDimStrong : TokenQuotaPanel_module_css_default.panelDim;
|
|
545
|
+
const panelDimClass = dimWhenIdle ? hovered || upgradeFlash ? "" : inputActive ? TokenQuotaPanel_module_css_default.panelDimStrong : TokenQuotaPanel_module_css_default.panelDim : "";
|
|
539
546
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
540
547
|
ref: panelRef,
|
|
541
548
|
className: `${TokenQuotaPanel_module_css_default.panel}${panelDimClass !== "" ? ` ${panelDimClass}` : ""}`,
|
|
@@ -565,13 +572,13 @@ window.__ModuleLoader__.load({
|
|
|
565
572
|
title: t("upgradeAvailableHint"),
|
|
566
573
|
children: [
|
|
567
574
|
"v",
|
|
568
|
-
"0.1.
|
|
575
|
+
"0.1.18",
|
|
569
576
|
" → v",
|
|
570
577
|
upgrade.latestVersion
|
|
571
578
|
]
|
|
572
579
|
}) : (0, react_jsx_runtime.jsxs)("span", {
|
|
573
580
|
className: TokenQuotaPanel_module_css_default.version,
|
|
574
|
-
children: ["v", "0.1.
|
|
581
|
+
children: ["v", "0.1.18"]
|
|
575
582
|
})]
|
|
576
583
|
}), (0, react_jsx_runtime.jsx)("div", {
|
|
577
584
|
className: TokenQuotaPanel_module_css_default.subtitle,
|
|
@@ -892,6 +899,22 @@ window.__ModuleLoader__.load({
|
|
|
892
899
|
})
|
|
893
900
|
]
|
|
894
901
|
}),
|
|
902
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
903
|
+
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
904
|
+
children: [(0, react_jsx_runtime.jsxs)("label", {
|
|
905
|
+
className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
|
|
906
|
+
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
907
|
+
type: "checkbox",
|
|
908
|
+
checked: dimWhenIdle,
|
|
909
|
+
onChange: (event) => {
|
|
910
|
+
setDimWhenIdle(event.target.checked);
|
|
911
|
+
}
|
|
912
|
+
}), (0, react_jsx_runtime.jsx)("span", { children: t("dimWhenIdleLabel") })]
|
|
913
|
+
}), (0, react_jsx_runtime.jsx)("div", {
|
|
914
|
+
className: TokenQuotaPanel_module_css_default.dialogHint,
|
|
915
|
+
children: t("dimWhenIdleHint")
|
|
916
|
+
})]
|
|
917
|
+
}),
|
|
895
918
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
896
919
|
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
897
920
|
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -1174,6 +1197,8 @@ window.__ModuleLoader__.load({
|
|
|
1174
1197
|
copied: "已复制 ✓",
|
|
1175
1198
|
upgradeHint: "升级后请重启 dsh web 并刷新浏览器页面",
|
|
1176
1199
|
checkUpdatesLabel: "自动检查更新",
|
|
1200
|
+
dimWhenIdleLabel: "失焦时窗口透明",
|
|
1201
|
+
dimWhenIdleHint: "鼠标移开面板时降低不透明度,输入文字时更透明;鼠标悬停恢复",
|
|
1177
1202
|
checkUpdatesNow: "立即检查",
|
|
1178
1203
|
checkingUpdates: "检查中…",
|
|
1179
1204
|
checkUpToDate: "已是最新",
|
|
@@ -1239,6 +1264,8 @@ window.__ModuleLoader__.load({
|
|
|
1239
1264
|
copied: "Copied ✓",
|
|
1240
1265
|
upgradeHint: "After upgrading, restart dsh web and refresh the browser",
|
|
1241
1266
|
checkUpdatesLabel: "Check for updates automatically",
|
|
1267
|
+
dimWhenIdleLabel: "Dim panel when unfocused",
|
|
1268
|
+
dimWhenIdleHint: "Fade the panel out when the pointer is away (more while typing); hover to restore",
|
|
1242
1269
|
checkUpdatesNow: "Check now",
|
|
1243
1270
|
checkingUpdates: "Checking…",
|
|
1244
1271
|
checkUpToDate: "Up to date",
|
|
@@ -1380,6 +1407,7 @@ window.__ModuleLoader__.load({
|
|
|
1380
1407
|
lastReset = doc?.reset !== void 0 && doc.reset !== null && typeof doc.reset === "object" && typeof doc.reset.offsetHours === "number" ? doc.reset : null;
|
|
1381
1408
|
bound?.setSettings(lastMonitored, lastOnFull);
|
|
1382
1409
|
bound?.setCheckUpdates(doc?.checkUpdates ?? true);
|
|
1410
|
+
bound?.setDimWhenIdle(doc?.dimWhenIdle ?? false);
|
|
1383
1411
|
bound?.setReset(lastReset);
|
|
1384
1412
|
fetch("/token-quota", { headers: { accept: "application/json" } }).then((response) => {
|
|
1385
1413
|
if (!response.ok) {
|
|
@@ -1445,6 +1473,10 @@ window.__ModuleLoader__.load({
|
|
|
1445
1473
|
bound?.setCheckUpdates(enabled);
|
|
1446
1474
|
scope.set("checkUpdates", enabled);
|
|
1447
1475
|
};
|
|
1476
|
+
const setDimWhenIdle = (enabled) => {
|
|
1477
|
+
bound?.setDimWhenIdle(enabled);
|
|
1478
|
+
scope.set("dimWhenIdle", enabled);
|
|
1479
|
+
};
|
|
1448
1480
|
/** Ask the Host to check the registry right now, then refresh the snapshot. */
|
|
1449
1481
|
const checkUpdatesNow = () => {
|
|
1450
1482
|
bound?.setCheckingUpdates(true);
|
|
@@ -1527,7 +1559,8 @@ window.__ModuleLoader__.load({
|
|
|
1527
1559
|
setReset,
|
|
1528
1560
|
setCheckUpdates,
|
|
1529
1561
|
checkUpdatesNow,
|
|
1530
|
-
clearLogBefore
|
|
1562
|
+
clearLogBefore,
|
|
1563
|
+
setDimWhenIdle
|
|
1531
1564
|
};
|
|
1532
1565
|
};
|
|
1533
1566
|
ctx.slots.inject("shell.overlay", () => ctx.slots.register({
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { assertTokenQuotaLimit, splitTokenQuotaKey } from "./invariant.js";
|
|
2
|
-
import {
|
|
2
|
+
import { mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
5
5
|
import { Service } from "@deepseek-ai/cordis";
|
|
@@ -91,13 +91,54 @@ function registryUpgradeCommands(profileDir, manager) {
|
|
|
91
91
|
function linkUpgradeCommands(linkPath) {
|
|
92
92
|
return [`git -C "${linkPath}" pull`];
|
|
93
93
|
}
|
|
94
|
-
/**
|
|
94
|
+
/**
|
|
95
|
+
* Detect the profile's package manager; defaults to npm.
|
|
96
|
+
*
|
|
97
|
+
* Lockfiles alone are unreliable: a profile can accumulate several of them over
|
|
98
|
+
* time (e.g. a leftover `pnpm-lock.yaml` next to a fresh `package-lock.json`
|
|
99
|
+
* after switching from pnpm to npm), and a bare existence check then reports
|
|
100
|
+
* the WRONG manager. Instead, look at the installer fingerprints inside
|
|
101
|
+
* `node_modules` — each manager leaves a marker when it actually installs —
|
|
102
|
+
* and pick the most recently touched one. Only if no marker exists fall back
|
|
103
|
+
* to comparing lockfile mtimes.
|
|
104
|
+
*/
|
|
95
105
|
function detectManager(dir) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
106
|
+
const stat = (path) => {
|
|
107
|
+
try {
|
|
108
|
+
return statSync(path).mtimeMs;
|
|
109
|
+
} catch {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
const fingerprints = [
|
|
114
|
+
["node_modules/.pnpm", "pnpm"],
|
|
115
|
+
["node_modules/.bun", "bun"],
|
|
116
|
+
["node_modules/.package-lock.json", "npm"],
|
|
117
|
+
["node_modules/.yarn-integrity", "yarn"]
|
|
118
|
+
];
|
|
119
|
+
let best;
|
|
120
|
+
for (const [rel, manager] of fingerprints) {
|
|
121
|
+
const mtime = stat(join(dir, rel));
|
|
122
|
+
if (mtime !== void 0 && (best === void 0 || mtime > best.mtime)) best = {
|
|
123
|
+
manager,
|
|
124
|
+
mtime
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
if (best !== void 0) return best.manager;
|
|
128
|
+
for (const [rel, manager] of [
|
|
129
|
+
["pnpm-lock.yaml", "pnpm"],
|
|
130
|
+
["yarn.lock", "yarn"],
|
|
131
|
+
["package-lock.json", "npm"],
|
|
132
|
+
["bun.lockb", "bun"],
|
|
133
|
+
["bun.lock", "bun"]
|
|
134
|
+
]) {
|
|
135
|
+
const mtime = stat(join(dir, rel));
|
|
136
|
+
if (mtime !== void 0 && (best === void 0 || mtime > best.mtime)) best = {
|
|
137
|
+
manager,
|
|
138
|
+
mtime
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
return best?.manager ?? "npm";
|
|
101
142
|
}
|
|
102
143
|
/**
|
|
103
144
|
* Locate the profile directory that declares this plugin as a dependency, along
|
|
@@ -116,7 +157,11 @@ function findProfile() {
|
|
|
116
157
|
for (const name of names) {
|
|
117
158
|
const dir = join(profilesDir, name);
|
|
118
159
|
const manifestPath = join(dir, "package.json");
|
|
119
|
-
|
|
160
|
+
try {
|
|
161
|
+
if (!statSync(manifestPath).isFile()) continue;
|
|
162
|
+
} catch {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
120
165
|
let manifest;
|
|
121
166
|
try {
|
|
122
167
|
manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
@@ -163,6 +208,7 @@ const TOKEN_QUOTA_SETTINGS_SCHEMA = z.object({
|
|
|
163
208
|
"switchPriority"
|
|
164
209
|
]).default("stop"),
|
|
165
210
|
checkUpdates: z.boolean().default(true),
|
|
211
|
+
dimWhenIdle: z.boolean().default(false),
|
|
166
212
|
reset: z.any().default(null)
|
|
167
213
|
});
|
|
168
214
|
/** Two-digit zero-pad helper. */
|
|
@@ -219,7 +265,8 @@ var TokenQuotaService = class TokenQuotaService extends Service {
|
|
|
219
265
|
limits: {},
|
|
220
266
|
monitored: [],
|
|
221
267
|
onFull: "stop",
|
|
222
|
-
checkUpdates: true
|
|
268
|
+
checkUpdates: true,
|
|
269
|
+
dimWhenIdle: false
|
|
223
270
|
});
|
|
224
271
|
/** Whether update checks are enabled (mirrors the settings document). */
|
|
225
272
|
checkUpdates = true;
|
|
@@ -266,6 +313,7 @@ var TokenQuotaService = class TokenQuotaService extends Service {
|
|
|
266
313
|
monitored: doc.monitored ?? [],
|
|
267
314
|
onFull: doc.onFull === "switchPriority" ? "switchAll" : doc.onFull ?? "stop",
|
|
268
315
|
checkUpdates: doc.checkUpdates ?? true,
|
|
316
|
+
dimWhenIdle: doc.dimWhenIdle ?? false,
|
|
269
317
|
reset: doc.reset ?? void 0
|
|
270
318
|
};
|
|
271
319
|
};
|
|
@@ -406,7 +454,7 @@ var TokenQuotaService = class TokenQuotaService extends Service {
|
|
|
406
454
|
return this.upgradeCheck;
|
|
407
455
|
}
|
|
408
456
|
async doRefreshUpgrade() {
|
|
409
|
-
const current = "0.1.
|
|
457
|
+
const current = "0.1.18";
|
|
410
458
|
let latest;
|
|
411
459
|
try {
|
|
412
460
|
const response = await fetch(REGISTRY_LATEST_URL, {
|
|
@@ -18,6 +18,8 @@ export interface TokenQuotaPanelInjected {
|
|
|
18
18
|
setReset: (reset: TokenQuotaReset | null) => void;
|
|
19
19
|
/** Persist whether the Host may check npm for newer versions. */
|
|
20
20
|
setCheckUpdates: (enabled: boolean) => void;
|
|
21
|
+
/** Persist whether the panel dims while the pointer is away / typing. */
|
|
22
|
+
setDimWhenIdle: (enabled: boolean) => void;
|
|
21
23
|
/** Ask the Host to check the registry right now, then refresh the snapshot. */
|
|
22
24
|
checkUpdatesNow: () => void;
|
|
23
25
|
/** Ask the Host to clear log entries before a date, then refresh the log. */
|
|
@@ -30,5 +32,5 @@ export type TokenQuotaPanelComponentProps = PropsRuntime<'shell.overlay'> & Prop
|
|
|
30
32
|
* @param props - composed slot props.
|
|
31
33
|
* @returns the panel element tree.
|
|
32
34
|
*/
|
|
33
|
-
export declare function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, useStore, actions, useSessions, }: TokenQuotaPanelComponentProps): import("react").JSX.Element;
|
|
35
|
+
export declare function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, setDimWhenIdle, useStore, actions, useSessions, }: TokenQuotaPanelComponentProps): import("react").JSX.Element;
|
|
34
36
|
//# sourceMappingURL=TokenQuotaPanel.d.ts.map
|
|
@@ -86,7 +86,7 @@ function loadPanelPos() {
|
|
|
86
86
|
* @param props - composed slot props.
|
|
87
87
|
* @returns the panel element tree.
|
|
88
88
|
*/
|
|
89
|
-
export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, useStore, actions, useSessions, }) {
|
|
89
|
+
export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, setDimWhenIdle, useStore, actions, useSessions, }) {
|
|
90
90
|
const [collapsed, setCollapsed] = useState(false);
|
|
91
91
|
const [drafts, setDrafts] = useState({});
|
|
92
92
|
const [editingKey, setEditingKey] = useState(null);
|
|
@@ -128,6 +128,7 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
|
|
|
128
128
|
const monitored = useStore(s => s.monitored);
|
|
129
129
|
const onFull = useStore(s => s.onFull);
|
|
130
130
|
const checkUpdates = useStore(s => s.checkUpdates);
|
|
131
|
+
const dimWhenIdle = useStore(s => s.dimWhenIdle);
|
|
131
132
|
const upgrade = useStore(s => s.upgrade);
|
|
132
133
|
const upgradeDismissed = useStore(s => s.upgradeDismissed);
|
|
133
134
|
const checkingUpdates = useStore(s => s.checkingUpdates);
|
|
@@ -285,12 +286,12 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
|
|
|
285
286
|
setLimit(row.key, parsed);
|
|
286
287
|
};
|
|
287
288
|
const visibleRows = rows.filter(row => isMonitoredKey(row.key) || row.current);
|
|
288
|
-
// The panel dims when the pointer is away
|
|
289
|
-
//
|
|
290
|
-
//
|
|
291
|
-
const panelDimClass =
|
|
292
|
-
? ''
|
|
293
|
-
:
|
|
289
|
+
// The panel dims when the pointer is away ONLY when the user opted in
|
|
290
|
+
// (settings → 失焦窗口透明). While the upgrade banner flashes, the panel
|
|
291
|
+
// is forced opaque regardless.
|
|
292
|
+
const panelDimClass = dimWhenIdle
|
|
293
|
+
? (hovered || upgradeFlash ? '' : inputActive ? css.panelDimStrong : css.panelDim)
|
|
294
|
+
: '';
|
|
294
295
|
return (_jsxs("div", { ref: panelRef, className: `${css.panel}${panelDimClass !== '' ? ` ${panelDimClass}` : ''}`, style: panelPos !== null ? { left: panelPos.x, top: panelPos.y, right: 'auto' } : undefined, onPointerEnter: () => { setHovered(true); }, onPointerLeave: () => { setHovered(false); }, children: [_jsxs("div", { className: css.header, onPointerDown: (event) => { beginDrag(event, panelRef.current, applyPanelPos); }, children: [_jsxs("div", { className: css.headerText, children: [_jsxs("div", { className: css.title, children: [t('title'), __TOKEN_QUOTA_VERSION__ !== undefined && __TOKEN_QUOTA_VERSION__ !== '' && (upgrade !== null
|
|
295
296
|
? (_jsxs("span", { className: `${css.version} ${css.versionNew}`, title: t('upgradeAvailableHint'), children: ["v", __TOKEN_QUOTA_VERSION__, " \u2192 v", upgrade.latestVersion] }))
|
|
296
297
|
: (_jsxs("span", { className: css.version, children: ["v", __TOKEN_QUOTA_VERSION__] })))] }), _jsx("div", { className: css.subtitle, children: t('subtitle') })] }), _jsxs("div", { className: css.headerActions, onPointerDown: (event) => { event.stopPropagation(); }, children: [_jsx("button", { type: "button", className: css.settingsBtn, onClick: () => { actions.setLogOpen(true); }, children: t('logs') }), _jsx("button", { type: "button", className: css.settingsBtn, onClick: openSettings, children: t('settings') }), _jsx("button", { type: "button", className: css.collapse, onClick: () => { setCollapsed(true); }, children: t('collapse') })] })] }), _jsxs("div", { className: css.body, children: [loading && _jsx("div", { className: css.notice, children: t('loading') }), error !== null && _jsx("div", { className: css.noticeError, children: error }), fullNotice !== null && (_jsx("div", { className: css.fullNotice, role: "alert", children: fullNotice })), upgrade !== null && !upgradeDismissed && (_jsxs("div", { className: `${css.upgradeBanner}${upgradeFlash ? ` ${css.upgradeBannerFlash}` : ''}`, role: "alert", children: [_jsx("div", { className: css.upgradeBannerText, children: t('upgradeAvailable').replace('{version}', upgrade.latestVersion) }), _jsx("div", { className: css.upgradeCommands, children: upgrade.commands.map(cmd => (_jsxs("div", { className: css.upgradeCommandRow, children: [_jsx("code", { className: css.upgradeCommand, children: cmd }), _jsx("button", { type: "button", className: `${css.copyBtn}${copiedCmd === cmd ? ` ${css.copyBtnDone}` : ''}`, onClick: () => { copyUpgradeCommand(cmd); }, children: copiedCmd === cmd ? t('copied') : t('copy') })] }, cmd))) }), _jsx("div", { className: css.upgradeHint, children: t('upgradeHint') }), _jsx("button", { type: "button", className: css.upgradeClose, onClick: () => { actions.setUpgradeDismissed(true); }, "aria-label": t('close'), children: "\u00D7" })] })), !loading && error === null && visibleRows.length === 0 && (_jsx("div", { className: css.notice, children: monitored !== null && monitored.length === 0 ? t('noMonitored') : t('waiting') })), visibleRows.map((row) => {
|
|
@@ -333,7 +334,7 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
|
|
|
333
334
|
hour: reset?.hour ?? 0,
|
|
334
335
|
minute: Number(event.target.value),
|
|
335
336
|
});
|
|
336
|
-
}, 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
|
|
337
|
+
}, 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("label", { className: css.checkUpdatesLabel, children: [_jsx("input", { type: "checkbox", checked: dimWhenIdle, onChange: (event) => { setDimWhenIdle(event.target.checked); } }), _jsx("span", { children: t('dimWhenIdleLabel') })] }), _jsx("div", { className: css.dialogHint, children: t('dimWhenIdleHint') })] }), _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
|
|
337
338
|
? t('checkingUpdates')
|
|
338
339
|
: lastCheckResult === 'up-to-date'
|
|
339
340
|
? t('checkUpToDate')
|
|
@@ -171,6 +171,7 @@ export function apply(ctx) {
|
|
|
171
171
|
: null;
|
|
172
172
|
bound?.setSettings(lastMonitored, lastOnFull);
|
|
173
173
|
bound?.setCheckUpdates(doc?.checkUpdates ?? true);
|
|
174
|
+
bound?.setDimWhenIdle(doc?.dimWhenIdle ?? false);
|
|
174
175
|
bound?.setReset(lastReset);
|
|
175
176
|
void fetch('/token-quota', { headers: { accept: 'application/json' } }).then((response) => {
|
|
176
177
|
if (!response.ok) {
|
|
@@ -234,6 +235,10 @@ export function apply(ctx) {
|
|
|
234
235
|
bound?.setCheckUpdates(enabled);
|
|
235
236
|
void scope.set('checkUpdates', enabled);
|
|
236
237
|
};
|
|
238
|
+
const setDimWhenIdle = (enabled) => {
|
|
239
|
+
bound?.setDimWhenIdle(enabled);
|
|
240
|
+
void scope.set('dimWhenIdle', enabled);
|
|
241
|
+
};
|
|
237
242
|
/** Ask the Host to check the registry right now, then refresh the snapshot. */
|
|
238
243
|
const checkUpdatesNow = () => {
|
|
239
244
|
bound?.setCheckingUpdates(true);
|
|
@@ -320,7 +325,7 @@ export function apply(ctx) {
|
|
|
320
325
|
bound = actions;
|
|
321
326
|
return {
|
|
322
327
|
load, setLimit, selectModel, setMonitored, setOnFull, setReset,
|
|
323
|
-
setCheckUpdates, checkUpdatesNow, clearLogBefore,
|
|
328
|
+
setCheckUpdates, checkUpdatesNow, clearLogBefore, setDimWhenIdle,
|
|
324
329
|
};
|
|
325
330
|
};
|
|
326
331
|
ctx.slots.inject('shell.overlay', () => ctx.slots.register({
|
|
@@ -64,6 +64,8 @@ export declare const zh: {
|
|
|
64
64
|
copied: string;
|
|
65
65
|
upgradeHint: string;
|
|
66
66
|
checkUpdatesLabel: string;
|
|
67
|
+
dimWhenIdleLabel: string;
|
|
68
|
+
dimWhenIdleHint: string;
|
|
67
69
|
checkUpdatesNow: string;
|
|
68
70
|
checkingUpdates: string;
|
|
69
71
|
checkUpToDate: string;
|
|
@@ -131,6 +133,8 @@ export declare const en: {
|
|
|
131
133
|
copied: string;
|
|
132
134
|
upgradeHint: string;
|
|
133
135
|
checkUpdatesLabel: string;
|
|
136
|
+
dimWhenIdleLabel: string;
|
|
137
|
+
dimWhenIdleHint: string;
|
|
134
138
|
checkUpdatesNow: string;
|
|
135
139
|
checkingUpdates: string;
|
|
136
140
|
checkUpToDate: string;
|
|
@@ -64,6 +64,8 @@ export const zh = {
|
|
|
64
64
|
copied: '已复制 ✓',
|
|
65
65
|
upgradeHint: '升级后请重启 dsh web 并刷新浏览器页面',
|
|
66
66
|
checkUpdatesLabel: '自动检查更新',
|
|
67
|
+
dimWhenIdleLabel: '失焦时窗口透明',
|
|
68
|
+
dimWhenIdleHint: '鼠标移开面板时降低不透明度,输入文字时更透明;鼠标悬停恢复',
|
|
67
69
|
checkUpdatesNow: '立即检查',
|
|
68
70
|
checkingUpdates: '检查中…',
|
|
69
71
|
checkUpToDate: '已是最新',
|
|
@@ -129,6 +131,8 @@ export const en = {
|
|
|
129
131
|
copied: 'Copied ✓',
|
|
130
132
|
upgradeHint: 'After upgrading, restart dsh web and refresh the browser',
|
|
131
133
|
checkUpdatesLabel: 'Check for updates automatically',
|
|
134
|
+
dimWhenIdleLabel: 'Dim panel when unfocused',
|
|
135
|
+
dimWhenIdleHint: 'Fade the panel out when the pointer is away (more while typing); hover to restore',
|
|
132
136
|
checkUpdatesNow: 'Check now',
|
|
133
137
|
checkingUpdates: 'Checking…',
|
|
134
138
|
checkUpToDate: 'Up to date',
|
|
@@ -48,6 +48,8 @@ export interface TokenQuotaPanelState {
|
|
|
48
48
|
onFull: TokenQuotaFullAction;
|
|
49
49
|
/** Whether the Host is allowed to check npm for newer versions. */
|
|
50
50
|
checkUpdates: boolean;
|
|
51
|
+
/** Whether the panel dims while the pointer is away / while typing. */
|
|
52
|
+
dimWhenIdle: boolean;
|
|
51
53
|
/** Latest upgrade availability from the Host; null = up to date or unknown. */
|
|
52
54
|
upgrade: TokenQuotaUpgrade | null;
|
|
53
55
|
/** Whether the one-shot upgrade banner was dismissed for the current latest version. */
|
|
@@ -89,6 +91,7 @@ export type TokenQuotaPanelActions = {
|
|
|
89
91
|
setError: (d: TokenQuotaPanelState, error: string | null) => void;
|
|
90
92
|
setSettings: (d: TokenQuotaPanelState, monitored: string[] | null, onFull: TokenQuotaFullAction) => void;
|
|
91
93
|
setCheckUpdates: (d: TokenQuotaPanelState, checkUpdates: boolean) => void;
|
|
94
|
+
setDimWhenIdle: (d: TokenQuotaPanelState, dimWhenIdle: boolean) => void;
|
|
92
95
|
setUpgrade: (d: TokenQuotaPanelState, upgrade: TokenQuotaUpgrade | null) => void;
|
|
93
96
|
setUpgradeDismissed: (d: TokenQuotaPanelState, dismissed: boolean) => void;
|
|
94
97
|
setCheckingUpdates: (d: TokenQuotaPanelState, checking: boolean) => void;
|
|
@@ -27,6 +27,7 @@ export function createTokenQuotaPanelStore() {
|
|
|
27
27
|
monitored: null,
|
|
28
28
|
onFull: 'stop',
|
|
29
29
|
checkUpdates: true,
|
|
30
|
+
dimWhenIdle: false,
|
|
30
31
|
upgrade: null,
|
|
31
32
|
upgradeDismissed: false,
|
|
32
33
|
checkingUpdates: false,
|
|
@@ -51,13 +52,23 @@ export function createTokenQuotaPanelStore() {
|
|
|
51
52
|
setError: (d, error) => { d.error = error; },
|
|
52
53
|
setSettings: (d, monitored, onFull) => { d.monitored = monitored; d.onFull = onFull; },
|
|
53
54
|
setCheckUpdates: (d, checkUpdates) => { d.checkUpdates = checkUpdates; },
|
|
55
|
+
setDimWhenIdle: (d, dimWhenIdle) => { d.dimWhenIdle = dimWhenIdle; },
|
|
54
56
|
setUpgrade: (d, upgrade) => {
|
|
57
|
+
// Guard against host/client version skew (e.g. the host process still
|
|
58
|
+
// runs an older bundle after an upgrade): when the reported "latest"
|
|
59
|
+
// equals the client's own version, there is nothing to upgrade to.
|
|
60
|
+
// This prevents a confusing `v0.1.16 → v0.1.16` banner.
|
|
61
|
+
const normalized = upgrade !== null
|
|
62
|
+
&& upgrade.latestVersion !== ''
|
|
63
|
+
&& upgrade.latestVersion !== __TOKEN_QUOTA_VERSION__
|
|
64
|
+
? upgrade
|
|
65
|
+
: null;
|
|
55
66
|
// A new latest version re-arms the one-shot banner; the same version
|
|
56
67
|
// stays dismissed until the user dismisses it again (or it changes).
|
|
57
|
-
if (d.upgrade === null || d.upgrade.latestVersion !==
|
|
68
|
+
if (d.upgrade === null || d.upgrade.latestVersion !== normalized?.latestVersion) {
|
|
58
69
|
d.upgradeDismissed = false;
|
|
59
70
|
}
|
|
60
|
-
d.upgrade =
|
|
71
|
+
d.upgrade = normalized;
|
|
61
72
|
},
|
|
62
73
|
setUpgradeDismissed: (d, dismissed) => { d.upgradeDismissed = dismissed; },
|
|
63
74
|
setCheckingUpdates: (d, checking) => { d.checkingUpdates = checking; },
|
package/lib/types/index.js
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
*
|
|
30
30
|
* @module @jxgame2020/dsh-token-quota
|
|
31
31
|
*/
|
|
32
|
-
import {
|
|
32
|
+
import { mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
|
|
33
33
|
import { homedir } from 'node:os';
|
|
34
34
|
import { dirname, join } from 'node:path';
|
|
35
35
|
import { Service } from '@deepseek-ai/cordis';
|
|
@@ -76,17 +76,57 @@ function registryUpgradeCommands(profileDir, manager) {
|
|
|
76
76
|
function linkUpgradeCommands(linkPath) {
|
|
77
77
|
return [`git -C "${linkPath}" pull`];
|
|
78
78
|
}
|
|
79
|
-
/**
|
|
79
|
+
/**
|
|
80
|
+
* Detect the profile's package manager; defaults to npm.
|
|
81
|
+
*
|
|
82
|
+
* Lockfiles alone are unreliable: a profile can accumulate several of them over
|
|
83
|
+
* time (e.g. a leftover `pnpm-lock.yaml` next to a fresh `package-lock.json`
|
|
84
|
+
* after switching from pnpm to npm), and a bare existence check then reports
|
|
85
|
+
* the WRONG manager. Instead, look at the installer fingerprints inside
|
|
86
|
+
* `node_modules` — each manager leaves a marker when it actually installs —
|
|
87
|
+
* and pick the most recently touched one. Only if no marker exists fall back
|
|
88
|
+
* to comparing lockfile mtimes.
|
|
89
|
+
*/
|
|
80
90
|
function detectManager(dir) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
91
|
+
const stat = (path) => {
|
|
92
|
+
try {
|
|
93
|
+
return statSync(path).mtimeMs;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
// Installer fingerprints inside node_modules, by manager.
|
|
100
|
+
const fingerprints = [
|
|
101
|
+
['node_modules/.pnpm', 'pnpm'],
|
|
102
|
+
['node_modules/.bun', 'bun'],
|
|
103
|
+
['node_modules/.package-lock.json', 'npm'],
|
|
104
|
+
['node_modules/.yarn-integrity', 'yarn'],
|
|
105
|
+
];
|
|
106
|
+
let best;
|
|
107
|
+
for (const [rel, manager] of fingerprints) {
|
|
108
|
+
const mtime = stat(join(dir, rel));
|
|
109
|
+
if (mtime !== undefined && (best === undefined || mtime > best.mtime)) {
|
|
110
|
+
best = { manager, mtime };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (best !== undefined)
|
|
114
|
+
return best.manager;
|
|
115
|
+
// Fallback: the most recently modified lockfile.
|
|
116
|
+
const lockfiles = [
|
|
117
|
+
['pnpm-lock.yaml', 'pnpm'],
|
|
118
|
+
['yarn.lock', 'yarn'],
|
|
119
|
+
['package-lock.json', 'npm'],
|
|
120
|
+
['bun.lockb', 'bun'],
|
|
121
|
+
['bun.lock', 'bun'],
|
|
122
|
+
];
|
|
123
|
+
for (const [rel, manager] of lockfiles) {
|
|
124
|
+
const mtime = stat(join(dir, rel));
|
|
125
|
+
if (mtime !== undefined && (best === undefined || mtime > best.mtime)) {
|
|
126
|
+
best = { manager, mtime };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return best?.manager ?? 'npm';
|
|
90
130
|
}
|
|
91
131
|
/**
|
|
92
132
|
* Locate the profile directory that declares this plugin as a dependency, along
|
|
@@ -108,8 +148,13 @@ function findProfile() {
|
|
|
108
148
|
for (const name of names) {
|
|
109
149
|
const dir = join(profilesDir, name);
|
|
110
150
|
const manifestPath = join(dir, 'package.json');
|
|
111
|
-
|
|
151
|
+
try {
|
|
152
|
+
if (!statSync(manifestPath).isFile())
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
112
156
|
continue;
|
|
157
|
+
}
|
|
113
158
|
let manifest;
|
|
114
159
|
try {
|
|
115
160
|
manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
@@ -156,6 +201,8 @@ const TOKEN_QUOTA_SETTINGS_SCHEMA = z.object({
|
|
|
156
201
|
// without reconfiguring.
|
|
157
202
|
onFull: z.union(['stop', 'switchQuota', 'switchAll', 'switchPriority']).default('stop'),
|
|
158
203
|
checkUpdates: z.boolean().default(true),
|
|
204
|
+
// Client-side appearance preference; the host only stores it.
|
|
205
|
+
dimWhenIdle: z.boolean().default(false),
|
|
159
206
|
// `reset` is a user-facing preference outside the validated surface: the
|
|
160
207
|
// panel writes it and the host validates the shape at runtime. `z.any` with
|
|
161
208
|
// a null default keeps it out of the strict fields above.
|
|
@@ -220,7 +267,7 @@ export class TokenQuotaService extends Service {
|
|
|
220
267
|
history = {};
|
|
221
268
|
limits = {};
|
|
222
269
|
monitored = undefined;
|
|
223
|
-
settingsSource = () => ({ limits: {}, monitored: [], onFull: 'stop', checkUpdates: true });
|
|
270
|
+
settingsSource = () => ({ limits: {}, monitored: [], onFull: 'stop', checkUpdates: true, dimWhenIdle: false });
|
|
224
271
|
/** Whether update checks are enabled (mirrors the settings document). */
|
|
225
272
|
checkUpdates = true;
|
|
226
273
|
/** Cached upgrade availability; recomputed by {@link refreshUpgrade}. */
|
|
@@ -275,6 +322,7 @@ export class TokenQuotaService extends Service {
|
|
|
275
322
|
// capped models first, then uncapped — both monitored-only.
|
|
276
323
|
onFull: doc.onFull === 'switchPriority' ? 'switchAll' : (doc.onFull ?? 'stop'),
|
|
277
324
|
checkUpdates: doc.checkUpdates ?? true,
|
|
325
|
+
dimWhenIdle: doc.dimWhenIdle ?? false,
|
|
278
326
|
reset: doc.reset ?? undefined,
|
|
279
327
|
};
|
|
280
328
|
};
|
package/lib/types/types.d.ts
CHANGED
|
@@ -68,6 +68,12 @@ export interface TokenQuotaSettings {
|
|
|
68
68
|
* and surfaces an update notice in the panel. `true` by default.
|
|
69
69
|
*/
|
|
70
70
|
checkUpdates: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Client-side appearance preference: dim the floating panel while the
|
|
73
|
+
* pointer is away (and more while typing) so the content behind stays
|
|
74
|
+
* readable. `false` by default — the panel stays fully opaque.
|
|
75
|
+
*/
|
|
76
|
+
dimWhenIdle: boolean;
|
|
71
77
|
/**
|
|
72
78
|
* Daily reset moment (timezone + clock time). Absent = machine-local
|
|
73
79
|
* midnight (the historical behaviour).
|
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.
|
|
4
|
+
"version": "0.1.18",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|