dsh-codex-subscription 1.3.0 → 1.4.0
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/AGENTS.md +5 -5
- package/README.md +4 -3
- package/README.zh-CN.md +3 -2
- package/docs/assets/composer-quota-en.png +0 -0
- package/docs/assets/settings-focus-en.png +0 -0
- package/docs/assets/settings-focus.png +0 -0
- package/lib/client.js +51 -30
- package/lib/index.js +23 -7
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -6,7 +6,7 @@ Use this guide when a user asks an Agent to install, update, verify, or remove
|
|
|
6
6
|
## Safety
|
|
7
7
|
|
|
8
8
|
- Confirm the target DSH installation and profile. Use `web` only when it is the user's target.
|
|
9
|
-
- Use the exact `1.
|
|
9
|
+
- Use the exact `1.4.0` package below; do not install a moving branch.
|
|
10
10
|
- Never print OAuth credentials, account IDs, authorization callbacks, or credential-store contents.
|
|
11
11
|
- Preserve the DSH profile, unrelated plugins, sessions, and saved sign-in.
|
|
12
12
|
- Do not start, stop, or restart DSH without explicit permission.
|
|
@@ -38,19 +38,19 @@ For an official DSH installation run through npm, keep the complete `npx` prefix
|
|
|
38
38
|
run command does not create a global `dsh` command:
|
|
39
39
|
|
|
40
40
|
```sh
|
|
41
|
-
npx -y @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add dsh-codex-subscription@1.
|
|
41
|
+
npx -y @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add dsh-codex-subscription@1.4.0
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
With an existing global `dsh` command:
|
|
45
45
|
|
|
46
46
|
```sh
|
|
47
|
-
dsh plugin --profile web add dsh-codex-subscription@1.
|
|
47
|
+
dsh plugin --profile web add dsh-codex-subscription@1.4.0
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
From a DSH-Portable folder:
|
|
51
51
|
|
|
52
52
|
```powershell
|
|
53
|
-
.\dsh.exe plugin --profile web add dsh-codex-subscription@1.
|
|
53
|
+
.\dsh.exe plugin --profile web add dsh-codex-subscription@1.4.0
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
Use the same `add` command to update or repair. This is the complete package-changing operation.
|
|
@@ -70,7 +70,7 @@ For DSH-Portable, replace `dsh` with `.\dsh.exe`. Static acceptance requires:
|
|
|
70
70
|
|
|
71
71
|
For the official npm route, run the same checks with `npx -y @deepseek-ai/dsh@0.1.1-rc.2` in place of `dsh`.
|
|
72
72
|
|
|
73
|
-
1. `dsh-codex-subscription` version `1.
|
|
73
|
+
1. `dsh-codex-subscription` version `1.4.0` appears exactly once.
|
|
74
74
|
2. `codex-subscription` appears exactly once in the composed config.
|
|
75
75
|
3. No unrelated plugin or profile was changed and DSH was not restarted.
|
|
76
76
|
|
package/README.md
CHANGED
|
@@ -46,6 +46,7 @@ From a DSH-Portable product folder, run `./dsh plugin ...` (`.\dsh.exe plugin ..
|
|
|
46
46
|
| **Subscription models** | Sign in to ChatGPT and use Codex without an OpenAI API key or Codex CLI |
|
|
47
47
|
| **Recoverable and diagnosable** | Sign-in state reconciles automatically; Settings can create a support report without credentials or account identifiers |
|
|
48
48
|
| **Visible quota** | Keep backend-provided standard Codex, Spark, and other limits separate |
|
|
49
|
+
| **Composer quota** | Choose a compact percentage, progress bar, or no inline quota display |
|
|
49
50
|
| **Safe quota reset** | Use a reset only for an exhausted Codex quota, with a cooldown, checkbox, and typed confirmation |
|
|
50
51
|
| **Subscription search** | Explicitly choose DSH default search or Codex subscription search |
|
|
51
52
|
| **Codex image generation** | Describe an image in a DSH conversation and view the generated result in that session |
|
|
@@ -144,7 +145,7 @@ Restart DSH manually after installation, then:
|
|
|
144
145
|
- Actual backend-provided quota, reset time, and freshness;
|
|
145
146
|
- Separate standard Codex, Codex-Spark, Credits, and other independent limits;
|
|
146
147
|
- Deliberate quota-reset redemption for exhausted Codex limits, with layered confirmation and no automatic retry;
|
|
147
|
-
- Optional
|
|
148
|
+
- Optional percentage or progress bar for the selected Codex model (off by default);
|
|
148
149
|
- Standard or Fast mode for supported Codex models directly in the composer (Beta);
|
|
149
150
|
- A copyable support report in Settings that excludes OAuth credentials, account identifiers, and authorization timestamps;
|
|
150
151
|
- Visible errors when subscription routing is unavailable, with no silent paid fallback.
|
|
@@ -155,8 +156,8 @@ Restart DSH manually after installation, then:
|
|
|
155
156
|
<img src="https://raw.githubusercontent.com/WSL043/dsh-codex-subscription/main/docs/assets/composer-quota-en.png" width="800" alt="Codex quota inside the composer">
|
|
156
157
|
</p>
|
|
157
158
|
|
|
158
|
-
The compact
|
|
159
|
-
window returned by the service; Spark uses its independent quota. The plugin does not hard-code a
|
|
159
|
+
Choose Off, Percent, or Progress bar in Settings. The compact display appears only for a selected Codex model.
|
|
160
|
+
Standard Codex uses the lowest remaining window returned by the service; Spark uses its independent quota. The plugin does not hard-code a
|
|
160
161
|
“5-hour + weekly” layout or invent Credits and spending caps that the service did not return.
|
|
161
162
|
|
|
162
163
|
### Safe quota reset
|
package/README.zh-CN.md
CHANGED
|
@@ -47,6 +47,7 @@ DSH-Portable 用户在产品目录中运行 `./dsh plugin ...`,Windows PowerSh
|
|
|
47
47
|
| **订阅模型直连** | 登录 ChatGPT 后直接使用 Codex,不需要 OpenAI API Key 或 Codex CLI |
|
|
48
48
|
| **可恢复、可诊断** | 登录状态会自动对账;设置页可生成不含凭据和账号标识的支持报告 |
|
|
49
49
|
| **额度可见** | 普通 Codex、Spark 等服务端实际返回的额度分开显示 |
|
|
50
|
+
| **输入框额度** | 可选择紧凑百分比、进度条或完全关闭输入框额度显示 |
|
|
50
51
|
| **安全额度重置** | 仅在 Codex 额度用尽后使用重置,并经过冷静期、勾选和输入确认 |
|
|
51
52
|
| **订阅搜索** | 可在 DSH 默认搜索与 Codex 订阅搜索之间明确切换 |
|
|
52
53
|
| **Codex 图片生成** | 在 DSH 对话里直接描述画面,生成结果会显示在当前会话中 |
|
|
@@ -144,7 +145,7 @@ DSH-Portable 请把 `dsh` 换成 `./dsh`(PowerShell 使用 `.\dsh.exe`)。
|
|
|
144
145
|
- 设置页显示服务端返回的额度、重置时间和更新时间;
|
|
145
146
|
- 普通 Codex、Codex-Spark、Credits 等独立额度分开显示;
|
|
146
147
|
- 已用尽的 Codex 额度可主动使用重置卡,并经过分层确认且不会自动重试;
|
|
147
|
-
-
|
|
148
|
+
- 输入框可用百分比或进度条显示当前 Codex 模型的剩余额度(默认关闭);
|
|
148
149
|
- 输入框可为支持的 Codex 模型切换标准或高速模式(Beta);
|
|
149
150
|
- 设置页可生成并复制无敏感信息的支持诊断,报告不包含 OAuth 凭据、账号标识或授权时间;
|
|
150
151
|
- 订阅路由不可用时明确报错,不会静默切换到其他付费路由。
|
|
@@ -155,7 +156,7 @@ DSH-Portable 请把 `dsh` 换成 `./dsh`(PowerShell 使用 `.\dsh.exe`)。
|
|
|
155
156
|
<img src="https://raw.githubusercontent.com/WSL043/dsh-codex-subscription/main/docs/assets/composer-quota-en.png" width="800" alt="输入框内的 Codex 剩余额度">
|
|
156
157
|
</p>
|
|
157
158
|
|
|
158
|
-
|
|
159
|
+
可在设置中选择关闭、百分比或进度条;紧凑额度只在选择 Codex 模型时显示。普通 Codex 使用服务端返回窗口中剩余最少的一项,
|
|
159
160
|
Spark 使用独立额度。插件不会写死“5 小时 + 每周”,也不会虚构服务端没有返回的 Credits 或消费上限。
|
|
160
161
|
|
|
161
162
|
### 安全使用额度重置
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/lib/client.js
CHANGED
|
@@ -50,7 +50,9 @@ window.__ModuleLoader__.load({
|
|
|
50
50
|
//#endregion
|
|
51
51
|
//#region src/settings-contract.js
|
|
52
52
|
const SETTINGS_NAMESPACE = "codex-subscription";
|
|
53
|
-
const
|
|
53
|
+
const QUICK_QUOTA_MODE_FIELD = "quickQuotaMode";
|
|
54
|
+
const LEGACY_QUICK_QUOTA_FIELD = "quickQuotaVisible";
|
|
55
|
+
const QUICK_QUOTA_MODE_PERCENT = "percent";
|
|
54
56
|
const SEARCH_PROVIDER_FIELD = "searchProvider";
|
|
55
57
|
const SEARCH_PROVIDER_CODEX = "codex";
|
|
56
58
|
const SPEED_MODE_FIELD = "speedMode";
|
|
@@ -59,6 +61,11 @@ window.__ModuleLoader__.load({
|
|
|
59
61
|
const DEFAULT_SPEED_MODE = SPEED_MODE_STANDARD;
|
|
60
62
|
const normalizeSearchProvider = (value) => ["dsh", "codex"].includes(value) ? value : "dsh";
|
|
61
63
|
const normalizeSpeedMode = (value) => ["standard", "fast"].includes(value) ? value : DEFAULT_SPEED_MODE;
|
|
64
|
+
const normalizeQuickQuotaMode = (value, legacyVisible = false) => [
|
|
65
|
+
"off",
|
|
66
|
+
"percent",
|
|
67
|
+
"bar"
|
|
68
|
+
].includes(value) ? value : legacyVisible === true ? QUICK_QUOTA_MODE_PERCENT : "off";
|
|
62
69
|
const supportsCodexFastMode = (modelId) => typeof modelId === "string" && (/^gpt-5\.(?:5|6)(?:$|-)/u.test(modelId) || modelId === "gpt-5.4");
|
|
63
70
|
//#endregion
|
|
64
71
|
//#region src/sidebar-quota.js
|
|
@@ -203,7 +210,9 @@ window.__ModuleLoader__.load({
|
|
|
203
210
|
spendReached: "Credits 月度消费上限已用尽。",
|
|
204
211
|
unavailable: "暂无数据",
|
|
205
212
|
quickQuotaSetting: "输入框额度",
|
|
206
|
-
|
|
213
|
+
quickQuotaOff: "关闭",
|
|
214
|
+
quickQuotaPercent: "百分比",
|
|
215
|
+
quickQuotaBar: "进度条",
|
|
207
216
|
quickQuotaStatus: "Codex 剩余额度 {value}%",
|
|
208
217
|
speedTitle: "速度",
|
|
209
218
|
speedStandard: "标准",
|
|
@@ -314,7 +323,9 @@ window.__ModuleLoader__.load({
|
|
|
314
323
|
spendReached: "The monthly Credits spending cap has been reached.",
|
|
315
324
|
unavailable: "No data yet",
|
|
316
325
|
quickQuotaSetting: "Composer quota",
|
|
317
|
-
|
|
326
|
+
quickQuotaOff: "Off",
|
|
327
|
+
quickQuotaPercent: "Percent",
|
|
328
|
+
quickQuotaBar: "Progress bar",
|
|
318
329
|
quickQuotaStatus: "Codex quota: {value}% remaining",
|
|
319
330
|
speedTitle: "Speed",
|
|
320
331
|
speedStandard: "Standard",
|
|
@@ -352,6 +363,7 @@ window.__ModuleLoader__.load({
|
|
|
352
363
|
.codexSubscriptionNote{font-size:13px;line-height:20px;color:var(--dsw-alias-label-tertiary)}
|
|
353
364
|
.codexSubscriptionCard{border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-1);padding:14px 16px;display:flex;flex-direction:column;gap:12px}
|
|
354
365
|
.codexSubscriptionUsageCard{padding:12px 14px;gap:9px}.codexSubscriptionPreferencesCard{padding:12px 14px;gap:10px}.codexSubscriptionPreference{min-height:32px;box-sizing:border-box;display:flex;align-items:center;justify-content:space-between;gap:12px;color:var(--dsw-alias-label-primary);font-size:13px;line-height:20px}.codexSubscriptionPreferenceCopy{display:flex;min-width:0;flex-direction:column;gap:2px}.codexSubscriptionPreferenceLabel{display:flex;align-items:center;gap:6px}
|
|
366
|
+
.codexSubscriptionQuotaModes{display:flex;align-items:center;gap:3px;padding:2px;border-radius:9px;background:var(--dsw-alias-bg-module-platform)}.codexSubscriptionQuotaMode{position:relative;display:flex;align-items:center;justify-content:center;min-height:26px;padding:0 9px;border-radius:7px;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;cursor:pointer}.codexSubscriptionQuotaMode:has(input:checked){background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);box-shadow:0 0 0 1px var(--dsw-alias-border-l3)}.codexSubscriptionQuotaMode:has(input:focus-visible){outline:2px solid var(--dsw-alias-border-l3);outline-offset:1px}.codexSubscriptionQuotaMode:has(input:disabled){cursor:not-allowed;opacity:.5}.codexSubscriptionQuotaMode input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
|
|
355
367
|
.codexSubscriptionSwitch{position:relative;flex:0 0 auto;width:32px;height:18px;padding:0;border:1px solid var(--dsw-alias-border-l3);border-radius:999px;background:var(--dsw-alias-bg-module-platform);cursor:pointer}.codexSubscriptionSwitch:disabled{cursor:not-allowed;opacity:.5}.codexSubscriptionSwitch[aria-checked=true]{background:var(--dsw-alias-label-secondary);border-color:var(--dsw-alias-label-secondary)}.codexSubscriptionSwitchKnob{position:absolute;top:2px;left:2px;width:12px;height:12px;border-radius:50%;background:var(--dsw-alias-bg-layer-1);transition:transform 120ms var(--ds-ease-in-out)}.codexSubscriptionSwitch[aria-checked=true] .codexSubscriptionSwitchKnob{transform:translateX(14px)}
|
|
356
368
|
.codexSubscriptionSearch{display:flex;flex-direction:column;gap:7px}.codexSubscriptionSearchChoices{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px}.codexSubscriptionSearchChoice{display:grid;grid-template-columns:14px minmax(0,1fr);align-items:center;column-gap:8px;min-width:0;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-primary);padding:9px 10px;text-align:left;cursor:pointer}.codexSubscriptionSearchChoice:has(input:disabled){cursor:not-allowed;opacity:.5}.codexSubscriptionSearchChoice:has(input:checked){border-color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.codexSubscriptionSearchChoice:has(input:focus-visible){outline:2px solid var(--dsw-alias-border-l3);outline-offset:2px}.codexSubscriptionSearchInput{width:14px;height:14px;margin:0;accent-color:var(--dsw-alias-label-primary);cursor:inherit}.codexSubscriptionSearchCopy{display:block;min-width:0;pointer-events:none}.codexSubscriptionSearchCopy strong,.codexSubscriptionSearchCopy span{display:block}.codexSubscriptionSearchCopy strong{font-size:12px;line-height:18px;font-weight:500;color:var(--dsw-alias-label-secondary)}.codexSubscriptionSearchChoice:has(input:checked) strong{color:var(--dsw-alias-label-primary)}.codexSubscriptionSearchCopy span{font-size:11px;line-height:16px;color:var(--dsw-alias-label-tertiary)}.codexSubscriptionDivider{height:1px;background:var(--dsw-alias-border-l2)}
|
|
357
369
|
.codexSubscriptionAccountRow,.codexSubscriptionSectionHead{display:flex;align-items:center;justify-content:space-between;gap:12px}.codexSubscriptionStatus{display:flex;align-items:center;gap:8px;font-size:14px;line-height:22px;font-weight:500}
|
|
@@ -372,7 +384,7 @@ window.__ModuleLoader__.load({
|
|
|
372
384
|
.codexSubscriptionCreditBalance{display:flex;flex-direction:column;gap:6px}.codexSubscriptionCreditBalance span,.codexSubscriptionCreditLabel{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary)}.codexSubscriptionCreditBalance strong{font:600 18px/24px ui-monospace,SFMono-Regular,Consolas,monospace;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
|
|
373
385
|
.codexSubscriptionResetSummary{display:flex;align-items:center;justify-content:space-between;gap:10px}.codexSubscriptionResetBalance{display:flex;flex-direction:column;gap:8px}.codexSubscriptionResetBalance .codexSubscriptionActions{justify-content:flex-start}.codexSubscriptionResetFlow{display:flex;flex-direction:column;gap:9px;border:1px solid var(--dsw-alias-state-warning-border,var(--dsw-alias-border-l2));border-radius:10px;padding:11px 12px;background:var(--dsw-alias-bg-module-platform)}.codexSubscriptionResetFlow h4{margin:0;font-size:13px;line-height:20px;font-weight:600}.codexSubscriptionResetWarning{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary)}.codexSubscriptionResetCheck{display:flex;align-items:flex-start;gap:8px;font-size:12px;line-height:18px;color:var(--dsw-alias-label-primary);cursor:pointer}.codexSubscriptionResetCheck input{margin:3px 0 0;accent-color:var(--dsw-alias-label-primary)}.codexSubscriptionResetPhrase{font:600 12px/18px ui-monospace,SFMono-Regular,Consolas,monospace}.codexSubscriptionResetFinal{border-color:var(--dsw-alias-state-error-primary)!important;color:var(--dsw-alias-state-error-primary)!important}.codexSubscriptionResetResult{font-size:12px;line-height:18px;color:var(--dsw-alias-state-success-primary)}
|
|
374
386
|
.codexSubscriptionSpendLimit{display:flex;flex-direction:column;gap:8px}.codexSubscriptionSpendTop{display:flex;align-items:baseline;justify-content:space-between;gap:12px}.codexSubscriptionSpendTop strong{font:600 16px/22px ui-monospace,SFMono-Regular,Consolas,monospace;font-variant-numeric:tabular-nums}.codexSubscriptionSpendLimit progress{width:100%;height:6px;border:0;border-radius:999px;overflow:hidden;background:var(--dsw-alias-border-l3);accent-color:var(--dsw-alias-brand-primary,#3964fe);-webkit-appearance:none;appearance:none}.codexSubscriptionSpendLimit progress::-webkit-progress-bar{background:var(--dsw-alias-border-l3);border-radius:999px}.codexSubscriptionSpendLimit progress::-webkit-progress-value{background:var(--dsw-alias-brand-primary,#3964fe);border-radius:999px}.codexSubscriptionSpendLimit progress::-moz-progress-bar{background:var(--dsw-alias-brand-primary,#3964fe);border-radius:999px}
|
|
375
|
-
.codexComposerQuota{display:inline-flex;align-items:center;flex:0 0 auto;height:28px;box-sizing:border-box;padding:0;color:var(--dsw-alias-label-secondary);font-family:inherit;font-size:12px;line-height:20px;font-weight:500;font-variant-numeric:tabular-nums;white-space:nowrap;user-select:none}
|
|
387
|
+
.codexComposerQuota{display:inline-flex;align-items:center;flex:0 0 auto;height:28px;box-sizing:border-box;padding:0;color:var(--dsw-alias-label-secondary);font-family:inherit;font-size:12px;line-height:20px;font-weight:500;font-variant-numeric:tabular-nums;white-space:nowrap;user-select:none}.codexComposerQuotaBar{display:block;width:40px;height:4px;border:0;border-radius:999px;overflow:hidden;background:var(--dsw-alias-border-l3);accent-color:var(--dsw-alias-label-secondary);-webkit-appearance:none;appearance:none}.codexComposerQuotaBar::-webkit-progress-bar{background:var(--dsw-alias-border-l3);border-radius:999px}.codexComposerQuotaBar::-webkit-progress-value{background:var(--dsw-alias-label-secondary);border-radius:999px}.codexComposerQuotaBar::-moz-progress-bar{background:var(--dsw-alias-label-secondary);border-radius:999px}
|
|
376
388
|
.codexModelSelect{position:relative;min-width:0}.codexModelSelectTrigger{display:flex;align-items:center;gap:4px;min-width:0;max-width:min(360px,45cqw);height:28px;padding:0 4px 0 8px;border:0;border-radius:24px;outline:0;background:transparent;color:var(--dsw-alias-label-secondary);font-size:13px;font-weight:500;line-height:20px;cursor:pointer}.codexModelSelectTrigger:hover:not(:disabled),.codexModelSelectTrigger[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover)}.codexModelSelectTrigger:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}.codexModelSelectTrigger:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}.codexModelSelectBolt{display:block;flex:none;width:14px;height:14px;color:var(--dsw-alias-label-primary)}.codexModelSelectLabel{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.codexModelSelectEffort{flex:none;color:var(--dsw-alias-label-caption)}.codexModelSelectChevron{flex:none;color:var(--dsw-alias-label-caption);transition:transform 120ms}.codexModelSelectTrigger[aria-expanded=true] .codexModelSelectChevron{transform:rotate(180deg)}
|
|
377
389
|
.codexModelSelectMenu,.codexModelSelectSubmenu{position:absolute;z-index:30;box-sizing:border-box;width:max-content;min-width:min(240px,calc(100vw - 32px));max-width:min(420px,calc(100vw - 32px));max-height:min(360px,calc(100vh - 96px));padding:4px;border:1px solid var(--dsw-alias-border-inverted);border-radius:12px;background:var(--dsw-specific-menu);box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);overflow:hidden}.codexModelSelectMenu{right:0;bottom:calc(100% + 8px)}.codexModelSelectSubmenu{right:calc(100% + 8px);bottom:0;min-width:min(230px,calc(100vw - 32px))}.codexModelSelectCell{display:flex;align-items:center;gap:8px;width:100%;min-width:100%;height:40px;box-sizing:border-box;padding:0 10px;border:0;border-radius:10px;background:transparent;color:inherit;font-size:14px;line-height:22px;text-align:left;cursor:pointer}.codexModelSelectCell:hover,.codexModelSelectCell:focus-visible,.codexModelSelectCell[data-open=true]{background:var(--dsw-alias-interactive-bg-hover);outline:0}.codexModelSelectCell:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}.codexModelSelectCellLabel{flex:none;white-space:nowrap}.codexModelSelectCellValue{flex:auto;min-width:0;overflow:hidden;color:var(--dsw-alias-label-tertiary);text-align:right;text-overflow:ellipsis;white-space:nowrap}.codexModelSelectCellChevron{flex:none;color:var(--dsw-alias-label-tertiary)}.codexModelSelectGroups{min-height:0;max-height:352px;overflow-y:auto}.codexModelSelectGroup+.codexModelSelectGroup{margin-top:4px}.codexModelSelectGroupTitle{position:sticky;top:0;z-index:1;padding:5px 8px 3px;background:var(--dsw-specific-menu);color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:500;line-height:18px}.codexModelSelectOption{display:flex;align-items:center;gap:8px;width:100%;min-width:100%;min-height:38px;box-sizing:border-box;padding:6px 8px;border:0;border-radius:10px;outline:0;background:transparent;color:inherit;text-align:left;cursor:pointer}.codexModelSelectOption:hover:not(:disabled),.codexModelSelectOption:focus-visible{background:var(--dsw-alias-interactive-bg-hover)}.codexModelSelectOption:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}.codexModelSelectOptionCopy{display:flex;flex:1;min-width:0;flex-direction:column}.codexModelSelectOptionName{overflow:hidden;color:inherit;font-size:14px;font-weight:500;line-height:20px;text-overflow:ellipsis;white-space:nowrap}.codexModelSelectOptionDescription{overflow:hidden;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;text-overflow:ellipsis;white-space:nowrap}.codexModelSelectCheck{display:grid;place-items:center;flex:0 0 18px;color:var(--dsw-alias-label-primary)}.codexModelSelectStatus,.codexModelSelectEmpty{padding:10px;color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:20px}.codexModelSelectError,.codexModelSelectWarning{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;margin-bottom:4px;padding:7px 8px;border-radius:8px;background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px}.codexModelSelectWarning{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-state-warn-label)}.codexModelSelectRetry{flex:none;padding:0;border:0;background:transparent;color:inherit;font:inherit;font-weight:600;cursor:pointer}
|
|
378
390
|
.codexModelSelectMenu{overflow:visible}
|
|
@@ -539,7 +551,7 @@ window.__ModuleLoader__.load({
|
|
|
539
551
|
const current = native.status === "ready" ? native : fallbackStatus === "ready" ? fallback : native;
|
|
540
552
|
return Object.freeze({
|
|
541
553
|
status: updating ? "updating" : current.status,
|
|
542
|
-
|
|
554
|
+
quickQuotaMode: normalizeQuickQuotaMode(current.value?.[QUICK_QUOTA_MODE_FIELD], current.value?.[LEGACY_QUICK_QUOTA_FIELD]),
|
|
543
555
|
searchProvider: normalizeSearchProvider(current.value?.[SEARCH_PROVIDER_FIELD]),
|
|
544
556
|
speedMode: normalizeSpeedMode(current.value?.[SPEED_MODE_FIELD]),
|
|
545
557
|
writable: !updating && current.status === "ready" && current.writable === true,
|
|
@@ -562,7 +574,7 @@ window.__ModuleLoader__.load({
|
|
|
562
574
|
fallback = {
|
|
563
575
|
status: "ready",
|
|
564
576
|
value: {
|
|
565
|
-
[
|
|
577
|
+
[QUICK_QUOTA_MODE_FIELD]: normalizeQuickQuotaMode(value?.[QUICK_QUOTA_MODE_FIELD], value?.[LEGACY_QUICK_QUOTA_FIELD]),
|
|
566
578
|
[SEARCH_PROVIDER_FIELD]: normalizeSearchProvider(value?.[SEARCH_PROVIDER_FIELD]),
|
|
567
579
|
[SPEED_MODE_FIELD]: normalizeSpeedMode(value?.[SPEED_MODE_FIELD])
|
|
568
580
|
},
|
|
@@ -683,33 +695,36 @@ window.__ModuleLoader__.load({
|
|
|
683
695
|
}
|
|
684
696
|
function QuickQuotaPreference({ preference, t }) {
|
|
685
697
|
const snapshot = usePreferenceSnapshot(preference);
|
|
686
|
-
const visible = snapshot.visible;
|
|
687
698
|
const writable = snapshot.status === "ready" && snapshot.writable === true;
|
|
699
|
+
const choice = (value, label) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
700
|
+
className: "codexSubscriptionQuotaMode",
|
|
701
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
702
|
+
type: "radio",
|
|
703
|
+
name: "codex-subscription-quota-mode",
|
|
704
|
+
checked: snapshot.quickQuotaMode === value,
|
|
705
|
+
disabled: !writable,
|
|
706
|
+
onChange: () => {
|
|
707
|
+
preference.set({ [QUICK_QUOTA_MODE_FIELD]: value });
|
|
708
|
+
}
|
|
709
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: label })]
|
|
710
|
+
});
|
|
688
711
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
689
712
|
className: "codexSubscriptionPreference",
|
|
690
713
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
691
714
|
className: "codexSubscriptionPreferenceCopy",
|
|
692
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.
|
|
715
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
693
716
|
className: "codexSubscriptionPreferenceLabel",
|
|
694
|
-
children:
|
|
695
|
-
className: "codexSubscriptionTag",
|
|
696
|
-
children: t("quickQuotaBeta")
|
|
697
|
-
})]
|
|
717
|
+
children: t("quickQuotaSetting")
|
|
698
718
|
})
|
|
699
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
700
|
-
className: "
|
|
701
|
-
|
|
702
|
-
role: "switch",
|
|
703
|
-
"aria-checked": visible,
|
|
719
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
720
|
+
className: "codexSubscriptionQuotaModes",
|
|
721
|
+
role: "radiogroup",
|
|
704
722
|
"aria-label": t("quickQuotaSetting"),
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
className: "codexSubscriptionSwitchKnob",
|
|
711
|
-
"aria-hidden": "true"
|
|
712
|
-
})
|
|
723
|
+
children: [
|
|
724
|
+
choice("off", t("quickQuotaOff")),
|
|
725
|
+
choice(QUICK_QUOTA_MODE_PERCENT, t("quickQuotaPercent")),
|
|
726
|
+
choice("bar", t("quickQuotaBar"))
|
|
727
|
+
]
|
|
713
728
|
})]
|
|
714
729
|
});
|
|
715
730
|
}
|
|
@@ -778,17 +793,23 @@ window.__ModuleLoader__.load({
|
|
|
778
793
|
const preferenceSnapshot = usePreferenceSnapshot(preference);
|
|
779
794
|
const current = (0, react.useSyncExternalStore)((listener) => directory.subscribe(listener), () => directory.getSnapshot()).current;
|
|
780
795
|
const codex = current?.provider === "openai-codex";
|
|
781
|
-
const quotaEnabled = preferenceSnapshot.status === "ready" && preferenceSnapshot.
|
|
796
|
+
const quotaEnabled = preferenceSnapshot.status === "ready" && preferenceSnapshot.quickQuotaMode !== "off" && codex;
|
|
782
797
|
const quota = useQuickQuota(rpc, quotaEnabled, current?.model);
|
|
783
798
|
if (!quotaEnabled || quota === void 0) return null;
|
|
784
|
-
const value =
|
|
785
|
-
const
|
|
786
|
-
|
|
799
|
+
const value = Math.round(Number(quota.remainingPercent) * 10) / 10;
|
|
800
|
+
const display = percent(value);
|
|
801
|
+
const label = fill(t("quickQuotaStatus"), { value: display });
|
|
802
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
787
803
|
className: "codexComposerQuota",
|
|
788
804
|
role: "status",
|
|
789
805
|
"aria-label": label,
|
|
790
806
|
title: label,
|
|
791
|
-
children:
|
|
807
|
+
children: preferenceSnapshot.quickQuotaMode === "bar" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("progress", {
|
|
808
|
+
className: "codexComposerQuotaBar",
|
|
809
|
+
max: 100,
|
|
810
|
+
value,
|
|
811
|
+
"aria-hidden": "true"
|
|
812
|
+
}) : `${display}%`
|
|
792
813
|
});
|
|
793
814
|
}
|
|
794
815
|
function CodexModelSelect({ locked, available, directory, load, select, preference, t }) {
|
package/lib/index.js
CHANGED
|
@@ -431,13 +431,20 @@ function createCodexRpcHandler(coordinator, options = {}) {
|
|
|
431
431
|
//#endregion
|
|
432
432
|
//#region src/settings-contract.js
|
|
433
433
|
const SETTINGS_NAMESPACE = "codex-subscription";
|
|
434
|
-
const
|
|
434
|
+
const QUICK_QUOTA_MODE_FIELD = "quickQuotaMode";
|
|
435
|
+
const LEGACY_QUICK_QUOTA_FIELD = "quickQuotaVisible";
|
|
436
|
+
const QUICK_QUOTA_MODE_PERCENT = "percent";
|
|
435
437
|
const SEARCH_PROVIDER_FIELD = "searchProvider";
|
|
436
438
|
const SEARCH_PROVIDER_CODEX = "codex";
|
|
437
439
|
const SPEED_MODE_FIELD = "speedMode";
|
|
438
440
|
const SPEED_MODE_STANDARD = "standard";
|
|
439
441
|
const SPEED_MODE_FAST = "fast";
|
|
440
442
|
const DEFAULT_SPEED_MODE = SPEED_MODE_STANDARD;
|
|
443
|
+
const normalizeQuickQuotaMode = (value, legacyVisible = false) => [
|
|
444
|
+
"off",
|
|
445
|
+
"percent",
|
|
446
|
+
"bar"
|
|
447
|
+
].includes(value) ? value : legacyVisible === true ? QUICK_QUOTA_MODE_PERCENT : "off";
|
|
441
448
|
const supportsCodexFastMode = (modelId) => typeof modelId === "string" && (/^gpt-5\.(?:5|6)(?:$|-)/u.test(modelId) || modelId === "gpt-5.4");
|
|
442
449
|
//#endregion
|
|
443
450
|
//#region src/pi-ai-runtime.js
|
|
@@ -496,7 +503,7 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0 } = {
|
|
|
496
503
|
}
|
|
497
504
|
//#endregion
|
|
498
505
|
//#region src/version.js
|
|
499
|
-
const PACKAGE_VERSION = "1.
|
|
506
|
+
const PACKAGE_VERSION = "1.4.0";
|
|
500
507
|
const USER_AGENT = `dsh-codex-subscription/${PACKAGE_VERSION}`;
|
|
501
508
|
//#endregion
|
|
502
509
|
//#region src/codex-search.js
|
|
@@ -1261,9 +1268,13 @@ function createSubscriptionRpcHandler({ authHandler, usageReader, resetCreditSer
|
|
|
1261
1268
|
signal.throwIfAborted();
|
|
1262
1269
|
if (endpoint === "preferences/update") {
|
|
1263
1270
|
const patch = {};
|
|
1264
|
-
if (Object.hasOwn(payload ?? {}, "
|
|
1265
|
-
if (
|
|
1266
|
-
|
|
1271
|
+
if (Object.hasOwn(payload ?? {}, "quickQuotaMode")) {
|
|
1272
|
+
if (![
|
|
1273
|
+
"off",
|
|
1274
|
+
"percent",
|
|
1275
|
+
"bar"
|
|
1276
|
+
].includes(payload["quickQuotaMode"])) return publicError("internal", "Invalid quick quota preference");
|
|
1277
|
+
patch[QUICK_QUOTA_MODE_FIELD] = payload[QUICK_QUOTA_MODE_FIELD];
|
|
1267
1278
|
}
|
|
1268
1279
|
if (Object.hasOwn(payload ?? {}, "searchProvider")) {
|
|
1269
1280
|
if (!["dsh", "codex"].includes(payload["searchProvider"])) return publicError("internal", "Invalid search provider preference");
|
|
@@ -1355,14 +1366,19 @@ function createSearchProviderSwitcher(loader) {
|
|
|
1355
1366
|
}
|
|
1356
1367
|
function apply(ctx) {
|
|
1357
1368
|
const settings = ctx.settings.register(settingsNamespace(SETTINGS_NAMESPACE), z.object({
|
|
1358
|
-
[
|
|
1369
|
+
[QUICK_QUOTA_MODE_FIELD]: z.union([
|
|
1370
|
+
"off",
|
|
1371
|
+
QUICK_QUOTA_MODE_PERCENT,
|
|
1372
|
+
"bar"
|
|
1373
|
+
]),
|
|
1374
|
+
[LEGACY_QUICK_QUOTA_FIELD]: z.boolean(),
|
|
1359
1375
|
[SEARCH_PROVIDER_FIELD]: z.union(["dsh", SEARCH_PROVIDER_CODEX]).default("dsh"),
|
|
1360
1376
|
[SPEED_MODE_FIELD]: z.union([SPEED_MODE_STANDARD, SPEED_MODE_FAST]).default(DEFAULT_SPEED_MODE)
|
|
1361
1377
|
}));
|
|
1362
1378
|
const searchProvider = createSearchProviderSwitcher(ctx.loader);
|
|
1363
1379
|
const preferences = {
|
|
1364
1380
|
status: () => ({
|
|
1365
|
-
[
|
|
1381
|
+
[QUICK_QUOTA_MODE_FIELD]: normalizeQuickQuotaMode(settings.get()[QUICK_QUOTA_MODE_FIELD], settings.get()[LEGACY_QUICK_QUOTA_FIELD]),
|
|
1366
1382
|
[SEARCH_PROVIDER_FIELD]: settings.get()[SEARCH_PROVIDER_FIELD],
|
|
1367
1383
|
[SPEED_MODE_FIELD]: settings.get()[SPEED_MODE_FIELD],
|
|
1368
1384
|
writable: ctx.settings.writable
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-codex-subscription",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
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",
|