dsh-codex-subscription 2.5.0 → 2.5.1
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/README.en.md +1 -1
- package/README.md +1 -1
- package/lib/client.js +90 -2
- package/lib/index.js +53 -4
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -105,7 +105,7 @@ This plugin supports the latest DeepSeek Harness release recorded in its package
|
|
|
105
105
|
2. Paste this package name, with its version, into the **Package name or address** field:
|
|
106
106
|
|
|
107
107
|
```text
|
|
108
|
-
dsh-codex-subscription@2.5.
|
|
108
|
+
dsh-codex-subscription@2.5.1
|
|
109
109
|
```
|
|
110
110
|
|
|
111
111
|
3. Click **Install** and wait for completion. Follow the page instructions; save your work before restarting if requested.
|
package/README.md
CHANGED
package/lib/client.js
CHANGED
|
@@ -5967,6 +5967,12 @@ window.__ModuleLoader__.load({
|
|
|
5967
5967
|
resetAccountChanged: "登录账号已变更,请重新开始。",
|
|
5968
5968
|
resetUncertain: "服务端返回结果不确定。请再次确认,插件会复用同一个请求,不会另外发起一次重置。",
|
|
5969
5969
|
creditsNote: "额外 Credits、消费上限、重置次数分别显示。",
|
|
5970
|
+
creditsExpires: "预计 {date} 到期,还剩 {days} 天",
|
|
5971
|
+
creditsExpiredToday: "今天 {date} 到期",
|
|
5972
|
+
creditsExpiryEstimate: "(估计:官方公布的 Pro 200 补偿 Credits 到期日,接口未返回,以 ChatGPT 使用情况页为准)",
|
|
5973
|
+
creditsAfterAllowance: "Credits 要等套餐额度用完后才会开始消耗,官方没有“先用 Credits”的开关。",
|
|
5974
|
+
creditsMessages: "约可发 {local} 条本地消息 / {cloud} 条云端消息",
|
|
5975
|
+
chatPass: "ChatPass 每周额度",
|
|
5970
5976
|
creditsUsed: "已用 {used} / {limit} credits",
|
|
5971
5977
|
spendReached: "Credits 月度消费上限已用尽。",
|
|
5972
5978
|
unavailable: "暂无数据",
|
|
@@ -6528,6 +6534,12 @@ window.__ModuleLoader__.load({
|
|
|
6528
6534
|
resetAccountChanged: "The signed-in account changed. Start again.",
|
|
6529
6535
|
resetUncertain: "The server result is uncertain. Confirm again to check the same request; the plugin will not start a separate reset.",
|
|
6530
6536
|
creditsNote: "Extra Credits, spending caps, and resets are separate items.",
|
|
6537
|
+
creditsExpires: "Expires {date} ({days} days left)",
|
|
6538
|
+
creditsExpiredToday: "Expires today ({date})",
|
|
6539
|
+
creditsExpiryEstimate: "(Estimate: the published expiry of the Pro 200 compensation Credits; the API does not report it, so check ChatGPT usage settings)",
|
|
6540
|
+
creditsAfterAllowance: "Credits are only drawn once the plan allowance runs out; there is no official switch to spend them first.",
|
|
6541
|
+
creditsMessages: "Roughly {local} local / {cloud} cloud messages",
|
|
6542
|
+
chatPass: "ChatPass weekly",
|
|
6531
6543
|
creditsUsed: "{used} / {limit} credits used",
|
|
6532
6544
|
spendReached: "The monthly Credits spending cap has been reached.",
|
|
6533
6545
|
unavailable: "No data yet",
|
|
@@ -6770,6 +6782,7 @@ window.__ModuleLoader__.load({
|
|
|
6770
6782
|
.codexSubscriptionSearchOptions[open]>summary{margin-bottom:8px}
|
|
6771
6783
|
.codexSubscriptionCreditSection{display:flex;flex-direction:column;gap:7px}
|
|
6772
6784
|
.codexSubscriptionCreditNote{font-size:11px;line-height:17px;color:var(--dsw-alias-label-tertiary)}
|
|
6785
|
+
.codexSubscriptionCreditExpiry{display:grid;gap:2px;font-size:11px;line-height:17px;color:var(--dsw-alias-label-tertiary)}.codexSubscriptionCreditExpiry p{margin:0}.codexSubscriptionCreditExpiry[data-soon=true]{color:var(--dsw-alias-label-secondary);font-weight:600}
|
|
6773
6786
|
.codexSubscriptionCreditRows{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:8px}
|
|
6774
6787
|
.codexSubscriptionCreditBalance,.codexSubscriptionSpendLimit{min-width:0;border-radius:10px;padding:12px 14px;background:var(--dsw-alias-bg-module-platform)}
|
|
6775
6788
|
.codexSubscriptionCreditBalance{display:flex;flex-direction:column;gap:6px}
|
|
@@ -8672,7 +8685,7 @@ window.__ModuleLoader__.load({
|
|
|
8672
8685
|
}
|
|
8673
8686
|
//#endregion
|
|
8674
8687
|
//#region src/version.js
|
|
8675
|
-
const PACKAGE_VERSION = "2.5.
|
|
8688
|
+
const PACKAGE_VERSION = "2.5.1";
|
|
8676
8689
|
//#endregion
|
|
8677
8690
|
//#region src/client-recovery.js
|
|
8678
8691
|
async function recoveryCall(rpc, endpoint, payload = {}, timeoutMs = 1e4) {
|
|
@@ -11296,8 +11309,38 @@ window.__ModuleLoader__.load({
|
|
|
11296
11309
|
]
|
|
11297
11310
|
});
|
|
11298
11311
|
}
|
|
11312
|
+
Object.freeze({
|
|
11313
|
+
credits: 62500,
|
|
11314
|
+
expiresAt: Date.UTC(2026, 11, 31, 12)
|
|
11315
|
+
});
|
|
11316
|
+
const DAY_MS = 864e5;
|
|
11317
|
+
/** Whole days left, and whether the expiry is close enough to call out. */
|
|
11318
|
+
function creditExpiryStatus(expiry, now = Date.now()) {
|
|
11319
|
+
if (expiry === void 0) return void 0;
|
|
11320
|
+
const daysLeft = Math.max(0, Math.ceil((expiry.expiresAt - now) / DAY_MS));
|
|
11321
|
+
return {
|
|
11322
|
+
daysLeft,
|
|
11323
|
+
soon: daysLeft <= 30
|
|
11324
|
+
};
|
|
11325
|
+
}
|
|
11299
11326
|
//#endregion
|
|
11300
11327
|
//#region src/client-usage.jsx
|
|
11328
|
+
const count = (value) => Number(value).toLocaleString();
|
|
11329
|
+
function CreditExpiry({ credits, t }) {
|
|
11330
|
+
const date = validDate(credits.expiresAt);
|
|
11331
|
+
if (date === void 0 || credits.unlimited) return null;
|
|
11332
|
+
const status = creditExpiryStatus({ expiresAt: credits.expiresAt });
|
|
11333
|
+
const estimate = credits.expirySource === "estimate";
|
|
11334
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
11335
|
+
className: "codexSubscriptionCreditExpiry",
|
|
11336
|
+
"data-soon": status.soon,
|
|
11337
|
+
role: "status",
|
|
11338
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", { children: [fill(t(status.daysLeft === 0 ? "creditsExpiredToday" : "creditsExpires"), {
|
|
11339
|
+
date: date.toLocaleDateString(),
|
|
11340
|
+
days: status.daysLeft
|
|
11341
|
+
}), estimate ? ` ${t("creditsExpiryEstimate")}` : ""] })
|
|
11342
|
+
});
|
|
11343
|
+
}
|
|
11301
11344
|
function ResetTime({ resetsAt, t }) {
|
|
11302
11345
|
const date = Number.isSafeInteger(resetsAt) ? validDate(resetsAt * 1e3) : void 0;
|
|
11303
11346
|
if (date === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("resetUnknown") });
|
|
@@ -11559,7 +11602,7 @@ window.__ModuleLoader__.load({
|
|
|
11559
11602
|
const visibleUsage = signedIn ? usage : void 0;
|
|
11560
11603
|
const limits = visibleUsage?.rateLimits ?? [];
|
|
11561
11604
|
const exhausted = limits.some((limit) => limit.id !== "code_review" && limit.windows.some((window) => window.usedPercent >= 100));
|
|
11562
|
-
const hasUsageDetails = limits.length > 0 || visibleUsage?.credits !== void 0 || visibleUsage?.individualLimit !== void 0 || visibleUsage?.resetCredits?.availableCount > 0;
|
|
11605
|
+
const hasUsageDetails = limits.length > 0 || visibleUsage?.chatPass !== void 0 || visibleUsage?.credits !== void 0 || visibleUsage?.individualLimit !== void 0 || visibleUsage?.resetCredits?.availableCount > 0;
|
|
11563
11606
|
const fetchedAt = typeof visibleUsage?.fetchedAt === "number" ? validDate(visibleUsage.fetchedAt) : void 0;
|
|
11564
11607
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
11565
11608
|
className: "codexSubscriptionCard codexSubscriptionUsageCard",
|
|
@@ -11642,6 +11685,36 @@ window.__ModuleLoader__.load({
|
|
|
11642
11685
|
]
|
|
11643
11686
|
}, `${limit.id}-${window.windowSeconds}-${index}`)))
|
|
11644
11687
|
}),
|
|
11688
|
+
visibleUsage?.chatPass === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
11689
|
+
className: "codexSubscriptionLimits",
|
|
11690
|
+
children: visibleUsage.chatPass.windows.map((window, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
11691
|
+
className: "codexSubscriptionLimit",
|
|
11692
|
+
children: [
|
|
11693
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
11694
|
+
className: "codexSubscriptionLimitTop",
|
|
11695
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
11696
|
+
className: "codexSubscriptionLimitLabel",
|
|
11697
|
+
children: t("chatPass")
|
|
11698
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("strong", { children: [percent(window.remainingPercent), "%"] })]
|
|
11699
|
+
}),
|
|
11700
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("progress", {
|
|
11701
|
+
max: "100",
|
|
11702
|
+
value: window.remainingPercent,
|
|
11703
|
+
"aria-label": `${t("chatPass")} ${fill(t("remaining"), { value: percent(window.remainingPercent) })}`
|
|
11704
|
+
}),
|
|
11705
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
11706
|
+
className: "codexSubscriptionLimitMeta",
|
|
11707
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
11708
|
+
className: "codexSubscriptionLimitPeriod",
|
|
11709
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: windowLabel(window.windowSeconds, t) })
|
|
11710
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResetTime, {
|
|
11711
|
+
resetsAt: window.resetsAt,
|
|
11712
|
+
t
|
|
11713
|
+
})]
|
|
11714
|
+
})
|
|
11715
|
+
]
|
|
11716
|
+
}, `chatpass-${window.windowSeconds}-${index}`))
|
|
11717
|
+
}),
|
|
11645
11718
|
visibleUsage?.credits === void 0 && visibleUsage?.individualLimit === void 0 && !(visibleUsage?.resetCredits?.availableCount > 0) ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
11646
11719
|
className: "codexSubscriptionCreditSection",
|
|
11647
11720
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
@@ -11654,6 +11727,21 @@ window.__ModuleLoader__.load({
|
|
|
11654
11727
|
className: "codexSubscriptionCreditBalance",
|
|
11655
11728
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("creditsBalance") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: visibleUsage.credits.unlimited ? t("unlimited") : `${visibleUsage.credits.balance ?? t("unavailable")} ${t("creditsUnit")}` })]
|
|
11656
11729
|
}) : null,
|
|
11730
|
+
visibleUsage?.credits ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CreditExpiry, {
|
|
11731
|
+
credits: visibleUsage.credits,
|
|
11732
|
+
t
|
|
11733
|
+
}) : null,
|
|
11734
|
+
visibleUsage?.credits && !visibleUsage.credits.unlimited ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
11735
|
+
className: "codexSubscriptionCreditNote",
|
|
11736
|
+
children: t("creditsAfterAllowance")
|
|
11737
|
+
}) : null,
|
|
11738
|
+
visibleUsage?.credits?.approxLocalMessages ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
11739
|
+
className: "codexSubscriptionCreditNote",
|
|
11740
|
+
children: fill(t("creditsMessages"), {
|
|
11741
|
+
local: `${count(visibleUsage.credits.approxLocalMessages[0])}–${count(visibleUsage.credits.approxLocalMessages[1])}`,
|
|
11742
|
+
cloud: visibleUsage.credits.approxCloudMessages ? `${count(visibleUsage.credits.approxCloudMessages[0])}–${count(visibleUsage.credits.approxCloudMessages[1])}` : t("unavailable")
|
|
11743
|
+
})
|
|
11744
|
+
}) : null,
|
|
11657
11745
|
visibleUsage?.resetCredits?.availableCount > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
|
|
11658
11746
|
className: "codexSubscriptionCreditBalance codexSubscriptionResetDisclosure",
|
|
11659
11747
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: fill(t("resetCreditsAvailable"), { count: visibleUsage.resetCredits.availableCount }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResetCreditList, {
|
package/lib/index.js
CHANGED
|
@@ -2043,7 +2043,7 @@ function inheritedOriginalImageRef(session, assetId) {
|
|
|
2043
2043
|
}
|
|
2044
2044
|
//#endregion
|
|
2045
2045
|
//#region src/version.js
|
|
2046
|
-
const PACKAGE_VERSION = "2.5.
|
|
2046
|
+
const PACKAGE_VERSION = "2.5.1";
|
|
2047
2047
|
const USER_AGENT = `dsh-codex-subscription/${PACKAGE_VERSION}`;
|
|
2048
2048
|
//#endregion
|
|
2049
2049
|
//#region src/codex-images.js
|
|
@@ -4824,6 +4824,24 @@ function safeCounters(source, keys) {
|
|
|
4824
4824
|
return Object.fromEntries(keys.filter((key) => Number.isSafeInteger(values?.[key]) && values[key] >= 0).map((key) => [key, values[key]]));
|
|
4825
4825
|
}
|
|
4826
4826
|
//#endregion
|
|
4827
|
+
//#region src/credit-expiry.js
|
|
4828
|
+
const PRO_200_COMPENSATION = Object.freeze({
|
|
4829
|
+
credits: 62500,
|
|
4830
|
+
expiresAt: Date.UTC(2026, 11, 31, 12)
|
|
4831
|
+
});
|
|
4832
|
+
/** Expiry of the balance: the API's own value when it has one, otherwise the known grant. */
|
|
4833
|
+
function creditExpiry({ planType, balance, apiExpiresAt }, now = Date.now()) {
|
|
4834
|
+
if (Number.isFinite(apiExpiresAt) && apiExpiresAt > now) return {
|
|
4835
|
+
expiresAt: apiExpiresAt,
|
|
4836
|
+
source: "api"
|
|
4837
|
+
};
|
|
4838
|
+
const amount = Number(balance);
|
|
4839
|
+
if (planType === "pro" && Number.isFinite(amount) && amount >= PRO_200_COMPENSATION.credits && now < PRO_200_COMPENSATION.expiresAt) return {
|
|
4840
|
+
expiresAt: PRO_200_COMPENSATION.expiresAt,
|
|
4841
|
+
source: "estimate"
|
|
4842
|
+
};
|
|
4843
|
+
}
|
|
4844
|
+
//#endregion
|
|
4827
4845
|
//#region src/usage.js
|
|
4828
4846
|
const CODEX_USAGE_URL = "https://chatgpt.com/backend-api/wham/usage";
|
|
4829
4847
|
const DEFAULT_TTL_MS = 6e4;
|
|
@@ -4865,15 +4883,44 @@ function epochSeconds(value, label) {
|
|
|
4865
4883
|
if (!Number.isSafeInteger(value) || value < 0) throw new Error(`Codex returned an invalid ${label}`);
|
|
4866
4884
|
return value;
|
|
4867
4885
|
}
|
|
4868
|
-
function
|
|
4886
|
+
function messageRange(value) {
|
|
4887
|
+
return Array.isArray(value) && value.length === 2 && value.every((item) => Number.isSafeInteger(item) && item >= 0) ? [value[0], value[1]] : void 0;
|
|
4888
|
+
}
|
|
4889
|
+
function expiryOf(value) {
|
|
4890
|
+
const raw = value?.expires_at;
|
|
4891
|
+
if (Number.isSafeInteger(raw) && raw > 0) return raw * 1e3;
|
|
4892
|
+
if (typeof raw === "string" && raw.length <= 64) {
|
|
4893
|
+
const parsed = Date.parse(raw);
|
|
4894
|
+
if (Number.isFinite(parsed) && parsed > 0) return parsed;
|
|
4895
|
+
}
|
|
4896
|
+
}
|
|
4897
|
+
function creditsOf(value, planType) {
|
|
4869
4898
|
if (value === void 0 || value === null) return void 0;
|
|
4870
4899
|
if (!record$1(value) || typeof value.has_credits !== "boolean" || typeof value.unlimited !== "boolean") throw new Error("Codex returned malformed credit details");
|
|
4871
4900
|
if (!value.has_credits) return void 0;
|
|
4901
|
+
const balance = value.balance === void 0 || value.balance === null ? void 0 : decimal(value.balance, "credit balance");
|
|
4902
|
+
const expiry = value.unlimited ? void 0 : creditExpiry({
|
|
4903
|
+
planType,
|
|
4904
|
+
balance,
|
|
4905
|
+
apiExpiresAt: expiryOf(value)
|
|
4906
|
+
});
|
|
4907
|
+
const local = messageRange(value.approx_local_messages), cloud = messageRange(value.approx_cloud_messages);
|
|
4872
4908
|
return {
|
|
4873
4909
|
unlimited: value.unlimited,
|
|
4874
|
-
...
|
|
4910
|
+
...balance === void 0 ? {} : { balance },
|
|
4911
|
+
...expiry === void 0 ? {} : {
|
|
4912
|
+
expiresAt: expiry.expiresAt,
|
|
4913
|
+
expirySource: expiry.source
|
|
4914
|
+
},
|
|
4915
|
+
...local === void 0 ? {} : { approxLocalMessages: local },
|
|
4916
|
+
...cloud === void 0 ? {} : { approxCloudMessages: cloud }
|
|
4875
4917
|
};
|
|
4876
4918
|
}
|
|
4919
|
+
function chatPassOf(value) {
|
|
4920
|
+
if (!record$1(value) || !Array.isArray(value.windows)) return void 0;
|
|
4921
|
+
const windows = value.windows.map(windowOf).filter(Boolean);
|
|
4922
|
+
return windows.length === 0 ? void 0 : { windows };
|
|
4923
|
+
}
|
|
4877
4924
|
function individualOf(value) {
|
|
4878
4925
|
if (value === void 0 || value === null) return void 0;
|
|
4879
4926
|
if (!record$1(value)) throw new Error("Codex returned malformed spend control");
|
|
@@ -4937,12 +4984,14 @@ function parseCodexUsage(value) {
|
|
|
4937
4984
|
addLimit(limitOf(entry.metered_feature, entry.limit_name || void 0, entry.rate_limit));
|
|
4938
4985
|
}
|
|
4939
4986
|
addLimit(limitOf("code_review", "Code review", value.code_review_rate_limit));
|
|
4940
|
-
const
|
|
4987
|
+
const chatPass = chatPassOf(value.chatpass);
|
|
4988
|
+
const credits = creditsOf(value.credits, typeof value.plan_type === "string" ? value.plan_type : void 0);
|
|
4941
4989
|
const individualLimit = individualOf(value.spend_control);
|
|
4942
4990
|
const spendControlReached = spendControlReachedOf(value.spend_control);
|
|
4943
4991
|
const resetCredits = resetCreditsOf(value.rate_limit_reset_credits);
|
|
4944
4992
|
return {
|
|
4945
4993
|
rateLimits,
|
|
4994
|
+
...chatPass === void 0 ? {} : { chatPass },
|
|
4946
4995
|
...credits === void 0 ? {} : { credits },
|
|
4947
4996
|
...individualLimit === void 0 ? {} : { individualLimit },
|
|
4948
4997
|
...spendControlReached === void 0 ? {} : { spendControlReached },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-codex-subscription",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.1",
|
|
4
4
|
"description": "Use ChatGPT and Codex subscriptions in DeepSeek Harness with OAuth, quota, safe resets, web search, images, and Fast mode",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|