dsh-codex-subscription 2.5.0 → 2.5.2
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 +57 -7
- 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.2
|
|
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.2";
|
|
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.2";
|
|
2047
2047
|
const USER_AGENT = `dsh-codex-subscription/${PACKAGE_VERSION}`;
|
|
2048
2048
|
//#endregion
|
|
2049
2049
|
//#region src/codex-images.js
|
|
@@ -2763,7 +2763,7 @@ function assertVaultRecord(record) {
|
|
|
2763
2763
|
return {
|
|
2764
2764
|
version: VERSION,
|
|
2765
2765
|
activeId: record.payload.activeId,
|
|
2766
|
-
legacyAccountId,
|
|
2766
|
+
...legacyAccountId === void 0 ? {} : { legacyAccountId },
|
|
2767
2767
|
accounts
|
|
2768
2768
|
};
|
|
2769
2769
|
}
|
|
@@ -2973,10 +2973,11 @@ var DshOAuthAccountVault = class {
|
|
|
2973
2973
|
if (!current.accounts.some((account) => account.id === id)) throw new Error("Unknown Codex account");
|
|
2974
2974
|
if (current.accounts.length === 1) throw new Error("Cannot remove the last account; sign out instead");
|
|
2975
2975
|
const accounts = current.accounts.filter((account) => account.id !== id);
|
|
2976
|
+
const { legacyAccountId, ...rest } = current;
|
|
2976
2977
|
return {
|
|
2977
|
-
...
|
|
2978
|
+
...rest,
|
|
2978
2979
|
activeId: current.activeId === id ? accounts[0].id : current.activeId,
|
|
2979
|
-
legacyAccountId
|
|
2980
|
+
...legacyAccountId === void 0 || legacyAccountId === id ? {} : { legacyAccountId },
|
|
2980
2981
|
accounts
|
|
2981
2982
|
};
|
|
2982
2983
|
});
|
|
@@ -4824,6 +4825,24 @@ function safeCounters(source, keys) {
|
|
|
4824
4825
|
return Object.fromEntries(keys.filter((key) => Number.isSafeInteger(values?.[key]) && values[key] >= 0).map((key) => [key, values[key]]));
|
|
4825
4826
|
}
|
|
4826
4827
|
//#endregion
|
|
4828
|
+
//#region src/credit-expiry.js
|
|
4829
|
+
const PRO_200_COMPENSATION = Object.freeze({
|
|
4830
|
+
credits: 62500,
|
|
4831
|
+
expiresAt: Date.UTC(2026, 11, 31, 12)
|
|
4832
|
+
});
|
|
4833
|
+
/** Expiry of the balance: the API's own value when it has one, otherwise the known grant. */
|
|
4834
|
+
function creditExpiry({ planType, balance, apiExpiresAt }, now = Date.now()) {
|
|
4835
|
+
if (Number.isFinite(apiExpiresAt) && apiExpiresAt > now) return {
|
|
4836
|
+
expiresAt: apiExpiresAt,
|
|
4837
|
+
source: "api"
|
|
4838
|
+
};
|
|
4839
|
+
const amount = Number(balance);
|
|
4840
|
+
if (planType === "pro" && Number.isFinite(amount) && amount >= PRO_200_COMPENSATION.credits && now < PRO_200_COMPENSATION.expiresAt) return {
|
|
4841
|
+
expiresAt: PRO_200_COMPENSATION.expiresAt,
|
|
4842
|
+
source: "estimate"
|
|
4843
|
+
};
|
|
4844
|
+
}
|
|
4845
|
+
//#endregion
|
|
4827
4846
|
//#region src/usage.js
|
|
4828
4847
|
const CODEX_USAGE_URL = "https://chatgpt.com/backend-api/wham/usage";
|
|
4829
4848
|
const DEFAULT_TTL_MS = 6e4;
|
|
@@ -4865,15 +4884,44 @@ function epochSeconds(value, label) {
|
|
|
4865
4884
|
if (!Number.isSafeInteger(value) || value < 0) throw new Error(`Codex returned an invalid ${label}`);
|
|
4866
4885
|
return value;
|
|
4867
4886
|
}
|
|
4868
|
-
function
|
|
4887
|
+
function messageRange(value) {
|
|
4888
|
+
return Array.isArray(value) && value.length === 2 && value.every((item) => Number.isSafeInteger(item) && item >= 0) ? [value[0], value[1]] : void 0;
|
|
4889
|
+
}
|
|
4890
|
+
function expiryOf(value) {
|
|
4891
|
+
const raw = value?.expires_at;
|
|
4892
|
+
if (Number.isSafeInteger(raw) && raw > 0) return raw * 1e3;
|
|
4893
|
+
if (typeof raw === "string" && raw.length <= 64) {
|
|
4894
|
+
const parsed = Date.parse(raw);
|
|
4895
|
+
if (Number.isFinite(parsed) && parsed > 0) return parsed;
|
|
4896
|
+
}
|
|
4897
|
+
}
|
|
4898
|
+
function creditsOf(value, planType) {
|
|
4869
4899
|
if (value === void 0 || value === null) return void 0;
|
|
4870
4900
|
if (!record$1(value) || typeof value.has_credits !== "boolean" || typeof value.unlimited !== "boolean") throw new Error("Codex returned malformed credit details");
|
|
4871
4901
|
if (!value.has_credits) return void 0;
|
|
4902
|
+
const balance = value.balance === void 0 || value.balance === null ? void 0 : decimal(value.balance, "credit balance");
|
|
4903
|
+
const expiry = value.unlimited ? void 0 : creditExpiry({
|
|
4904
|
+
planType,
|
|
4905
|
+
balance,
|
|
4906
|
+
apiExpiresAt: expiryOf(value)
|
|
4907
|
+
});
|
|
4908
|
+
const local = messageRange(value.approx_local_messages), cloud = messageRange(value.approx_cloud_messages);
|
|
4872
4909
|
return {
|
|
4873
4910
|
unlimited: value.unlimited,
|
|
4874
|
-
...
|
|
4911
|
+
...balance === void 0 ? {} : { balance },
|
|
4912
|
+
...expiry === void 0 ? {} : {
|
|
4913
|
+
expiresAt: expiry.expiresAt,
|
|
4914
|
+
expirySource: expiry.source
|
|
4915
|
+
},
|
|
4916
|
+
...local === void 0 ? {} : { approxLocalMessages: local },
|
|
4917
|
+
...cloud === void 0 ? {} : { approxCloudMessages: cloud }
|
|
4875
4918
|
};
|
|
4876
4919
|
}
|
|
4920
|
+
function chatPassOf(value) {
|
|
4921
|
+
if (!record$1(value) || !Array.isArray(value.windows)) return void 0;
|
|
4922
|
+
const windows = value.windows.map(windowOf).filter(Boolean);
|
|
4923
|
+
return windows.length === 0 ? void 0 : { windows };
|
|
4924
|
+
}
|
|
4877
4925
|
function individualOf(value) {
|
|
4878
4926
|
if (value === void 0 || value === null) return void 0;
|
|
4879
4927
|
if (!record$1(value)) throw new Error("Codex returned malformed spend control");
|
|
@@ -4937,12 +4985,14 @@ function parseCodexUsage(value) {
|
|
|
4937
4985
|
addLimit(limitOf(entry.metered_feature, entry.limit_name || void 0, entry.rate_limit));
|
|
4938
4986
|
}
|
|
4939
4987
|
addLimit(limitOf("code_review", "Code review", value.code_review_rate_limit));
|
|
4940
|
-
const
|
|
4988
|
+
const chatPass = chatPassOf(value.chatpass);
|
|
4989
|
+
const credits = creditsOf(value.credits, typeof value.plan_type === "string" ? value.plan_type : void 0);
|
|
4941
4990
|
const individualLimit = individualOf(value.spend_control);
|
|
4942
4991
|
const spendControlReached = spendControlReachedOf(value.spend_control);
|
|
4943
4992
|
const resetCredits = resetCreditsOf(value.rate_limit_reset_credits);
|
|
4944
4993
|
return {
|
|
4945
4994
|
rateLimits,
|
|
4995
|
+
...chatPass === void 0 ? {} : { chatPass },
|
|
4946
4996
|
...credits === void 0 ? {} : { credits },
|
|
4947
4997
|
...individualLimit === void 0 ? {} : { individualLimit },
|
|
4948
4998
|
...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.2",
|
|
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",
|