dsh-deepseek-balance-widget 2.3.7 → 2.3.9
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 +57 -2
- package/lib/index.js +10 -0
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -40,6 +40,8 @@ window.__ModuleLoader__.load({
|
|
|
40
40
|
updating: "更新中…",
|
|
41
41
|
updateSuccess: "成功,请重启 dsh",
|
|
42
42
|
updateFailed: "更新失败",
|
|
43
|
+
updateFailedHint: "自动更新未成功,请手动更新:重启 dsh 后点「检查更新」重试,或前往 GitHub 自行安装最新版。",
|
|
44
|
+
githubUrl: "https://github.com/crazy-L118/dsh-deepseek-balance-widget",
|
|
43
45
|
failed: "失败",
|
|
44
46
|
usageUnavailable: "用量接口不可用({0})",
|
|
45
47
|
usageNotConfigured: "未配置 DEEPSEEK_PLATFORM_TOKEN,仅显示余额。对 AI 说「帮我配置用量统计」,AI 会帮你设置(可选)。",
|
|
@@ -110,6 +112,7 @@ window.__ModuleLoader__.load({
|
|
|
110
112
|
pasteCookieHint: "请粘贴 Cookie 或 cURL,AI 会自动提取",
|
|
111
113
|
copied: "已复制",
|
|
112
114
|
copyFailed: "复制失败",
|
|
115
|
+
copyError: "复制错误信息",
|
|
113
116
|
refresh: "刷新",
|
|
114
117
|
peakPeriod: "繁忙时段",
|
|
115
118
|
offPeakPeriod: "空闲时段"
|
|
@@ -125,6 +128,8 @@ window.__ModuleLoader__.load({
|
|
|
125
128
|
updating: "Updating…",
|
|
126
129
|
updateSuccess: "Success, please restart dsh",
|
|
127
130
|
updateFailed: "Update failed",
|
|
131
|
+
updateFailedHint: "Auto-update did not succeed. Please update manually: restart dsh and click \"Check for updates\" to retry, or visit GitHub to install the latest version yourself.",
|
|
132
|
+
githubUrl: "https://github.com/crazy-L118/dsh-deepseek-balance-widget",
|
|
128
133
|
failed: "Failed",
|
|
129
134
|
usageUnavailable: "Usage API unavailable ({0})",
|
|
130
135
|
usageNotConfigured: "DEEPSEEK_PLATFORM_TOKEN not configured, showing balance only. Tell the AI 'help me configure usage stats' to set it up (optional).",
|
|
@@ -195,6 +200,7 @@ window.__ModuleLoader__.load({
|
|
|
195
200
|
pasteCookieHint: "Paste a Cookie or cURL; the AI will extract it",
|
|
196
201
|
copied: "Copied",
|
|
197
202
|
copyFailed: "Copy failed",
|
|
203
|
+
copyError: "Copy error",
|
|
198
204
|
refresh: "Refresh",
|
|
199
205
|
peakPeriod: "Peak",
|
|
200
206
|
offPeakPeriod: "Off-peak"
|
|
@@ -420,7 +426,15 @@ window.__ModuleLoader__.load({
|
|
|
420
426
|
".dshBalanceWizardLink:hover{color:#79b8ff}",
|
|
421
427
|
".dshBalanceCookiePreview{font-size:11px;color:#7b8494;background:rgba(255,255,255,.05);border-radius:6px;padding:6px 8px;word-break:break-all}",
|
|
422
428
|
".dshBalanceCookiePreview code{color:#e6e9ef;font-size:10px}",
|
|
423
|
-
".dshBalanceCookiePreview[data-found=false]{display:none}"
|
|
429
|
+
".dshBalanceCookiePreview[data-found=false]{display:none}",
|
|
430
|
+
".dshBalanceUpdateErr{margin-top:10px;border:1px solid rgba(248,81,73,.25);border-radius:8px;background:rgba(248,81,73,.08);padding:8px 10px}",
|
|
431
|
+
".dshBalanceUpdateErrHead{display:flex;justify-content:space-between;align-items:center;font-size:12px;font-weight:600;color:#f85149;margin-bottom:6px}",
|
|
432
|
+
".dshBalanceUpdateErrClose{appearance:none;background:transparent;border:0;color:#9aa4b2;font-size:18px;line-height:1;cursor:pointer;padding:0 2px}",
|
|
433
|
+
".dshBalanceUpdateErrClose:hover{color:#f85149}",
|
|
434
|
+
".dshBalanceUpdateErrBody{max-height:120px;overflow:auto;background:#0f1216;border:1px solid rgba(255,255,255,.08);border-radius:6px;padding:6px 8px;margin:0 0 8px;font-family:ui-monospace,Menlo,Consolas,monospace;font-size:10px;line-height:1.4;color:#c9d1d9;white-space:pre-wrap;word-break:break-all}",
|
|
435
|
+
".dshBalanceUpdateErrHint{font-size:11px;line-height:1.5;color:#e6edf3;margin:0 0 8px}",
|
|
436
|
+
".dshBalanceUpdateErrHint a{color:#58a6ff;text-decoration:underline;word-break:break-all}",
|
|
437
|
+
".dshBalanceUpdateErrHint a:hover{color:#79c0ff}"
|
|
424
438
|
].join("");
|
|
425
439
|
const tag = document.createElement("style");
|
|
426
440
|
tag.dataset.plugin = "dsh-deepseek-balance-widget";
|
|
@@ -565,6 +579,8 @@ window.__ModuleLoader__.load({
|
|
|
565
579
|
} else {
|
|
566
580
|
btn.textContent = t("updateFailed");
|
|
567
581
|
btn.title = String(result.error || t("updateFailed")) + (result.output ? "\n" + result.output.slice(-200) : "");
|
|
582
|
+
updateErrorDetail = { error: result.error || t("updateFailed"), output: result.output || "" };
|
|
583
|
+
renderPopover();
|
|
568
584
|
setTimeout(() => { btn.textContent = originalText; btn.disabled = false; btn.title = ""; }, 3000);
|
|
569
585
|
}
|
|
570
586
|
}
|
|
@@ -835,6 +851,24 @@ window.__ModuleLoader__.load({
|
|
|
835
851
|
if (updateBtn !== null) {
|
|
836
852
|
updateBtn.addEventListener("click", () => handleUpdateClick(updateBtn));
|
|
837
853
|
}
|
|
854
|
+
const updateErrClose = popRef.querySelector("[data-update-err-close]");
|
|
855
|
+
if (updateErrClose !== null) {
|
|
856
|
+
updateErrClose.addEventListener("click", () => { updateErrorDetail = null; renderPopover(); });
|
|
857
|
+
}
|
|
858
|
+
const updateErrCopy = popRef.querySelector("[data-update-err-copy]");
|
|
859
|
+
if (updateErrCopy !== null) {
|
|
860
|
+
updateErrCopy.addEventListener("click", () => {
|
|
861
|
+
if (!updateErrorDetail) return;
|
|
862
|
+
const text = String(updateErrorDetail.error || "") + "\n" + String(updateErrorDetail.output || "");
|
|
863
|
+
navigator.clipboard?.writeText(text).then(() => {
|
|
864
|
+
updateErrCopy.textContent = t("copied");
|
|
865
|
+
setTimeout(() => updateErrCopy.textContent = t("copyError"), 1500);
|
|
866
|
+
}).catch(() => {
|
|
867
|
+
updateErrCopy.textContent = t("copyFailed");
|
|
868
|
+
setTimeout(() => updateErrCopy.textContent = t("copyError"), 1500);
|
|
869
|
+
});
|
|
870
|
+
});
|
|
871
|
+
}
|
|
838
872
|
const addBtn = popRef.querySelector("[data-add]");
|
|
839
873
|
if (addBtn !== null) addBtn.addEventListener("click", () => { addFormState = { kind: "mimo", label: "", key: "", cookie: "" }; showAddForm = true; renderPopover(); });
|
|
840
874
|
const cancelBtn = popRef.querySelector("[data-cancel]");
|
|
@@ -1221,11 +1255,30 @@ window.__ModuleLoader__.load({
|
|
|
1221
1255
|
}
|
|
1222
1256
|
const updated = lastUpdated ? lastUpdated.toLocaleTimeString() : "—";
|
|
1223
1257
|
const versionHtml = versionHtmlOf(lastVersion);
|
|
1258
|
+
const errorPanel = updateErrorDetail ? updateErrorHtml(updateErrorDetail) : "";
|
|
1224
1259
|
return header + syncHint + body +
|
|
1225
1260
|
'<div class="dshBalanceFoot">' + versionHtml +
|
|
1226
1261
|
'<span style="display:flex;align-items:center;gap:8px">' +
|
|
1227
1262
|
'<button class="dshBalanceBtn" type="button" data-refresh>' + t("refresh") + "</button>" +
|
|
1228
|
-
'<span>' + t("updatedAt") + updated + "</span></span></div>";
|
|
1263
|
+
'<span>' + t("updatedAt") + updated + "</span></span></div>" + errorPanel;
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
/** Render the update-failure detail panel shown below the footer. */
|
|
1267
|
+
function updateErrorHtml(detail) {
|
|
1268
|
+
const summary = String(detail.error || t("updateFailed"));
|
|
1269
|
+
const text = (detail.output || "").trim();
|
|
1270
|
+
const snippet = text.slice(-500) || summary;
|
|
1271
|
+
const escaped = snippet.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
1272
|
+
return '<div class="dshBalanceUpdateErr">' +
|
|
1273
|
+
'<div class="dshBalanceUpdateErrHead">' +
|
|
1274
|
+
'<span>' + t("updateFailed") + "</span>" +
|
|
1275
|
+
'<button class="dshBalanceUpdateErrClose" type="button" data-update-err-close aria-label="close">×</button>' +
|
|
1276
|
+
"</div>" +
|
|
1277
|
+
'<pre class="dshBalanceUpdateErrBody" title="' + t("updateFailed") + '">' + escaped + "</pre>" +
|
|
1278
|
+
'<p class="dshBalanceUpdateErrHint">' + t("updateFailedHint") +
|
|
1279
|
+
' <a href="' + t("githubUrl") + '" target="_blank" rel="noopener">' + t("githubUrl") + "</a></p>" +
|
|
1280
|
+
'<button class="dshBalanceBtn" type="button" data-update-err-copy>' + t("copyError") + "</button>" +
|
|
1281
|
+
"</div>";
|
|
1229
1282
|
}
|
|
1230
1283
|
|
|
1231
1284
|
/** Build the npm version snippet shown in the footer (always a clickable button). */
|
|
@@ -1452,6 +1505,8 @@ window.__ModuleLoader__.load({
|
|
|
1452
1505
|
let timer = null;
|
|
1453
1506
|
let versionTimer = null;
|
|
1454
1507
|
let updateSuccessUntil = 0;
|
|
1508
|
+
/** When the last update attempt failed, hold {error, output} so the user can inspect it. */
|
|
1509
|
+
let updateErrorDetail = null;
|
|
1455
1510
|
|
|
1456
1511
|
/** One refresh cycle: fetch balance + usage + providers, update entry and popover. */
|
|
1457
1512
|
async function refresh(manual) {
|
package/lib/index.js
CHANGED
|
@@ -601,12 +601,22 @@ function cleanEnv() {
|
|
|
601
601
|
const env = { ...process.env };
|
|
602
602
|
const no = env.NODE_OPTIONS || "";
|
|
603
603
|
if (/genie-safe-delete/i.test(no)) {
|
|
604
|
+
// Strip the WorkBuddy safe-delete shim entirely. The shim monkey-patches
|
|
605
|
+
// fs.unlink/rm to route through a trash channel which is disabled inside
|
|
606
|
+
// the desktop sandbox, causing pnpm/npm to fail-closed whenever they delete
|
|
607
|
+
// temporary files during an install. Removing the --require prevents the
|
|
608
|
+
// child Node process from loading it at all.
|
|
604
609
|
env.NODE_OPTIONS = no
|
|
605
610
|
.replace(/\s*--require="[^"]*genie-safe-delete[^"]*"/gi, "")
|
|
606
611
|
.replace(/\s*--require=[^\s"]*genie-safe-delete[^\s"]*/gi, "")
|
|
607
612
|
.trim();
|
|
608
613
|
if (!env.NODE_OPTIONS) delete env.NODE_OPTIONS;
|
|
609
614
|
}
|
|
615
|
+
// Also delete any remaining WorkBuddy/shim variables that can re-enable
|
|
616
|
+
// safe-delete behavior in spawned package managers.
|
|
617
|
+
delete env.WORKBUDDY_SAFE_DELETE;
|
|
618
|
+
delete env.GENIE_SAFE_DELETE;
|
|
619
|
+
delete env.SAFE_DELETE_ENABLED;
|
|
610
620
|
env.NPM_CONFIG_FUND = "false";
|
|
611
621
|
env.NPM_CONFIG_AUDIT = "false";
|
|
612
622
|
return env;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-deepseek-balance-widget",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Multi-provider AI balance widget for the dsh web sidebar: a live, auto-refreshing balance pill plus a detail popover listing DeepSeek and any added providers (MiMo etc.). Keys are stored per-machine in ~/.dsh/ai-balances.json and resolved from the local credential seam, never hardcoded.",
|
|
6
6
|
"keywords": [
|