dsh-codex-subscription 2.7.0 → 2.7.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 CHANGED
@@ -106,7 +106,7 @@ This plugin supports the latest DeepSeek Harness release recorded in its package
106
106
  2. Paste this package name, with its version, into the **Package name or address** field:
107
107
 
108
108
  ```text
109
- dsh-codex-subscription@2.7.0
109
+ dsh-codex-subscription@2.7.1
110
110
  ```
111
111
 
112
112
  3. Click **Install** and wait for completion. Follow the page instructions; save your work before restarting if requested.
@@ -118,7 +118,7 @@ Why the version is included: DSH's plugin page only installs versions that are a
118
118
  <summary>Terminal installation (with an existing dsh command)</summary>
119
119
 
120
120
  ```sh
121
- dsh plugin --profile web add dsh-codex-subscription@2.7.0
121
+ dsh plugin --profile web add dsh-codex-subscription@2.7.1
122
122
  ```
123
123
 
124
124
  Follow the restart instructions, then sign in under **Settings → Codex**. Both the Plugins page and the terminal use DSH's installation management.
@@ -131,7 +131,7 @@ Follow the restart instructions, then sign in under **Settings → Codex**. Both
131
131
  After signing in and selecting a Codex model in Web, install the same plugin in the Headless profile:
132
132
 
133
133
  ```sh
134
- dsh plugin --profile headless add dsh-codex-subscription@2.7.0
134
+ dsh plugin --profile headless add dsh-codex-subscription@2.7.1
135
135
  dsh --profile headless "Reply with only the word: ok"
136
136
  ```
137
137
 
@@ -266,7 +266,7 @@ Find this plugin on the DSH **Plugins** page and use its update or uninstall act
266
266
  <summary>Terminal commands</summary>
267
267
 
268
268
  ```sh
269
- dsh plugin --profile web update dsh-codex-subscription@2.7.0
269
+ dsh plugin --profile web update dsh-codex-subscription@2.7.1
270
270
  ```
271
271
 
272
272
  Run only when you want to uninstall:
@@ -282,7 +282,7 @@ dsh plugin --profile web remove dsh-codex-subscription
282
282
  <details>
283
283
  <summary>DSH 0.2.0-rc.2 reports the plugin as incompatible?</summary>
284
284
 
285
- DSH 0.2.0-rc.2 did not exist when any release before 2.2.10 was published, and a published package's compatibility declaration cannot be changed. Install 2.2.10 or later (a bare package name can resolve to an older release during the first 24 hours, so enter `dsh-codex-subscription@2.2.10`) from the **Plugins** page, or run `dsh plugin --profile web update dsh-codex-subscription@2.7.0`, then restart DSH.
285
+ DSH 0.2.0-rc.2 did not exist when any release before 2.2.10 was published, and a published package's compatibility declaration cannot be changed. Install 2.2.10 or later (a bare package name can resolve to an older release during the first 24 hours, so enter `dsh-codex-subscription@2.2.10`) from the **Plugins** page, or run `dsh plugin --profile web update dsh-codex-subscription@2.7.1`, then restart DSH.
286
286
 
287
287
  </details>
288
288
 
package/README.md CHANGED
@@ -106,7 +106,7 @@
106
106
  2. 在 **包名或地址** 输入框中粘贴下面的包名(已带版本号):
107
107
 
108
108
  ```text
109
- dsh-codex-subscription@2.7.0
109
+ dsh-codex-subscription@2.7.1
110
110
  ```
111
111
 
112
112
  3. 点击 **安装**,等待安装完成;按页面提示操作,需要重启时先保存工作。
@@ -118,7 +118,7 @@
118
118
  <summary>终端安装(已能运行 dsh 命令)</summary>
119
119
 
120
120
  ```sh
121
- dsh plugin --profile web add dsh-codex-subscription@2.7.0
121
+ dsh plugin --profile web add dsh-codex-subscription@2.7.1
122
122
  ```
123
123
 
124
124
  安装完成后按提示重启 DSH,再到 **设置 → Codex 订阅** 登录。插件页面和终端均由 DSH 管理安装。
@@ -131,7 +131,7 @@ dsh plugin --profile web add dsh-codex-subscription@2.7.0
131
131
  先在 Web 中完成登录并选择一次 Codex 模型,再把同一个插件安装到 Headless profile:
132
132
 
133
133
  ```sh
134
- dsh plugin --profile headless add dsh-codex-subscription@2.7.0
134
+ dsh plugin --profile headless add dsh-codex-subscription@2.7.1
135
135
  dsh --profile headless "只回复:ok"
136
136
  ```
137
137
 
@@ -295,7 +295,7 @@ DSH 实机设置截图。
295
295
  <summary>终端方式</summary>
296
296
 
297
297
  ```sh
298
- dsh plugin --profile web update dsh-codex-subscription@2.7.0
298
+ dsh plugin --profile web update dsh-codex-subscription@2.7.1
299
299
  ```
300
300
 
301
301
  仅在需要卸载时运行:
@@ -311,7 +311,7 @@ dsh plugin --profile web remove dsh-codex-subscription
311
311
  <details>
312
312
  <summary>DSH 0.2.0-rc.2 提示插件不兼容?</summary>
313
313
 
314
- 2.2.10 之前的所有版本发布时 DSH 0.2.0-rc.2 还不存在,其兼容声明无法事后修改。请安装 2.2.10 或更高版本(只填包名时,发布满 24 小时前可能装到旧版,请直接填 `dsh-codex-subscription@2.2.10`):在 **插件** 页面更新,或运行 `dsh plugin --profile web update dsh-codex-subscription@2.7.0`,然后重启 DSH。
314
+ 2.2.10 之前的所有版本发布时 DSH 0.2.0-rc.2 还不存在,其兼容声明无法事后修改。请安装 2.2.10 或更高版本(只填包名时,发布满 24 小时前可能装到旧版,请直接填 `dsh-codex-subscription@2.2.10`):在 **插件** 页面更新,或运行 `dsh plugin --profile web update dsh-codex-subscription@2.7.1`,然后重启 DSH。
315
315
 
316
316
  </details>
317
317
 
package/lib/client.js CHANGED
@@ -5469,6 +5469,8 @@ window.__ModuleLoader__.load({
5469
5469
  const IconChevronDownOutline14 = _deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14 ?? _deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular;
5470
5470
  const IconChevronRightOutline14 = _deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14 ?? _deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular;
5471
5471
  const Menu = _deepseek_ai_dsh_client_ui_primitives.Menu;
5472
+ const MenuSurface = _deepseek_ai_dsh_client_ui_primitives.MenuSurface;
5473
+ const MenuGroup = _deepseek_ai_dsh_client_ui_primitives.MenuGroup;
5472
5474
  const Tooltip = _deepseek_ai_dsh_client_ui_primitives.Tooltip;
5473
5475
  const IconChevronLeftOutline14 = _deepseek_ai_dsh_client_ui_primitives.IconChevronLeftOutline14 ?? _deepseek_ai_dsh_client_ui_primitives.IconChevronLeftOutlineRegular;
5474
5476
  const IconCloseOutline16 = _deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16 ?? _deepseek_ai_dsh_client_ui_primitives.IconCloseOutlineRegular;
@@ -6985,7 +6987,7 @@ window.__ModuleLoader__.load({
6985
6987
  .codexComposerQuotaBar::-webkit-progress-value{background:var(--dsw-alias-label-secondary);border-radius:999px}
6986
6988
  .codexComposerQuotaBar::-moz-progress-bar{background:var(--dsw-alias-label-secondary);border-radius:999px}
6987
6989
  .codexModelSelect{position:relative;min-width:0}
6988
- .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}
6990
+ .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:var(--dsw-radius-sm);outline:0;background:transparent;color:var(--dsw-alias-label-secondary);font-size:13px;font-weight:500;line-height:20px;cursor:pointer}
6989
6991
  .codexModelSelectTrigger:hover:not(:disabled),.codexModelSelectTrigger[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover)}
6990
6992
  .codexModelSelectTrigger:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}
6991
6993
  .codexModelSelectTrigger:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}
@@ -6994,34 +6996,32 @@ window.__ModuleLoader__.load({
6994
6996
  .codexModelSelectEffort{flex:none;color:var(--dsw-alias-label-caption)}
6995
6997
  .codexModelSelectChevron{flex:none;color:var(--dsw-alias-label-caption);transition:transform 120ms}
6996
6998
  .codexModelSelectTrigger[aria-expanded=true] .codexModelSelectChevron{transform:rotate(180deg)}
6997
- .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-alias-bg-layer-2,#2c2c2e);box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);overflow:hidden}
6998
- .codexModelSelectMenu{right:0;bottom:calc(100% + 8px)}
6999
- .codexModelSelectSubmenu{right:calc(100% + 8px);bottom:0;min-width:min(230px,calc(100vw - 32px))}
7000
- /* Keep search outside the scroll viewport; let the model list fit the bounded menu. */
7001
- .codexModelSelectModelMenu{display:flex;flex-direction:column}
7002
- .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}
7003
- .codexModelSelectCell:hover,.codexModelSelectCell:focus-visible,.codexModelSelectCell[data-open=true]{background:var(--dsw-alias-interactive-bg-hover);outline:0}
7004
- .codexModelSelectCell:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}
6999
+ /* The menu follows DSH's own model picker: one floating surface above the trigger, rows drill into the same surface. */
7000
+ .codexModelSelectMenu{z-index:1100;--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);box-sizing:border-box;position:fixed;display:flex;flex-direction:column;width:max-content;min-width:min(240px,100vw - 32px);max-width:min(420px,100vw - 32px);max-height:min(360px,100vh - 96px);padding:4px;border:0;box-shadow:var(--dsw-elevation-prominent);color:var(--dsw-alias-label-primary);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);overflow:hidden}
7001
+ .codexModelSelectCell{box-sizing:border-box;display:flex;align-items:center;gap:6px;width:auto;min-width:100%;height:34px;padding:0 8px;border:none;border-radius:var(--dsw-radius-md);outline:none;background:transparent;color:var(--dsw-alias-label-primary);font-size:13px;line-height:20px;text-align:left;cursor:pointer}
7002
+ .codexModelSelectCell:hover,.codexModelSelectCell:focus-visible{background:var(--dsw-alias-interactive-bg-hover)}
7005
7003
  .codexModelSelectCellLabel{flex:none;white-space:nowrap}
7006
7004
  .codexModelSelectCellValue{flex:auto;min-width:0;overflow:hidden;color:var(--dsw-alias-label-tertiary);text-align:right;text-overflow:ellipsis;white-space:nowrap}
7007
- .codexModelSelectCellChevron{flex:none;color:var(--dsw-alias-label-tertiary)}
7008
- .codexModelSelectSearch{display:block;flex-shrink:0;width:100%;box-sizing:border-box;height:32px;margin:0 0 4px;padding:0 10px;border:1px solid var(--dsw-alias-border-l3);border-radius:8px;outline:0;background:transparent;color:inherit;font:inherit;font-size:13px}
7009
- .codexModelSelectSearch:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}
7005
+ .codexModelSelectCellChevron{flex:none;width:12px;height:12px;color:var(--dsw-alias-menu-icon)}
7006
+ .codexModelSelectSearchRow{flex-shrink:0;position:relative;margin:2px 0 3px}
7007
+ .codexModelSelectSearchRow .codexModelSelectSearch{display:flex;height:auto;padding:5px 7px;border:0 solid transparent;border-radius:var(--dsw-radius-md);background:transparent}
7008
+ .codexModelSelectSearchRow .codexModelSelectSearch:focus-within{border-color:transparent}
7009
+ .codexModelSelectSearchRow .codexModelSelectSearch input{padding:0;font-size:12px;line-height:normal}
7010
+ .codexModelSelectSearchRow .codexModelSelectSearch input::placeholder{color:var(--dsw-alias-label-caption)}
7010
7011
  .codexModelSelectGroups{flex:1 1 auto;min-height:0;overflow-y:auto}
7011
- .codexModelSelectGroup+.codexModelSelectGroup{margin-top:4px}
7012
- .codexModelSelectGroupTitle{position:sticky;top:0;z-index:1;padding:5px 8px 3px;background:var(--dsw-alias-bg-layer-2,#2c2c2e);color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:500;line-height:18px}
7013
- .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}
7012
+ .codexModelSelectGroupTitle{padding:5px 8px 3px;color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:500;line-height:18px}
7013
+ .codexModelSelectOption{box-sizing:border-box;display:flex;align-items:center;gap:6px;width:auto;min-width:100%;min-height:34px;padding:5px 7px;border:none;border-radius:var(--dsw-radius-md);outline:none;background:transparent;color:inherit;text-align:left;cursor:pointer}
7014
7014
  .codexModelSelectOption:hover:not(:disabled),.codexModelSelectOption:focus-visible{background:var(--dsw-alias-interactive-bg-hover)}
7015
7015
  .codexModelSelectOption:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}
7016
- .codexModelSelectOptionCopy{display:flex;flex:1;min-width:0;flex-direction:column}
7017
- .codexModelSelectOptionName{overflow:hidden;color:inherit;font-size:14px;font-weight:500;line-height:20px;text-overflow:ellipsis;white-space:nowrap}
7018
- .codexModelSelectOptionDescription{overflow:hidden;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;text-overflow:ellipsis;white-space:nowrap}
7019
- .codexModelSelectCheck{display:grid;place-items:center;flex:0 0 18px;color:var(--dsw-alias-label-primary)}
7020
- .codexModelSelectStatus,.codexModelSelectEmpty{padding:10px;color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:20px}
7021
- .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}
7016
+ .codexModelSelectOptionCopy{display:flex;flex:1;flex-direction:column;min-width:0}
7017
+ .codexModelSelectOptionName{overflow:hidden;color:inherit;font-size:13px;font-weight:400;line-height:18px;text-overflow:ellipsis;white-space:nowrap}
7018
+ .codexModelSelectOptionDescription{overflow:hidden;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:16px;text-overflow:ellipsis;white-space:nowrap}
7019
+ .codexModelSelectCheck{display:grid;place-items:center;flex:0 0 14px;color:var(--dsw-alias-label-primary)}
7020
+ .codexModelSelectCheck svg{width:14px;height:14px}
7021
+ .codexModelSelectStatus,.codexModelSelectEmpty{padding:8px;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}
7022
+ .codexModelSelectError,.codexModelSelectWarning{display:flex;align-items:flex-start;justify-content:space-between;gap:6px;margin-bottom:3px;padding:6px 7px;border-radius:var(--dsw-radius-md);background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary);font-size:11px;line-height:16px}
7022
7023
  .codexModelSelectWarning{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-state-warn-label)}
7023
- .codexModelSelectRetry{flex:none;padding:0;border:0;background:transparent;color:inherit;font:inherit;font-weight:600;cursor:pointer}
7024
- .codexModelSelectMenu{overflow:visible}
7024
+ .codexModelSelectRetry{flex:none;padding:0;border:none;background:transparent;color:inherit;font:inherit;font-weight:600;cursor:pointer}
7025
7025
  .codexImageTool{display:flex;flex-direction:column;gap:8px;margin:4px 0;color:var(--dsw-alias-label-primary)}
7026
7026
  .codexImageToolRow{display:flex;align-items:center;min-height:24px;gap:8px;font-size:13px;line-height:20px}
7027
7027
  .codexImageToolIcon{display:block;flex-shrink:0;width:16px;height:16px;color:var(--dsw-alias-label-secondary)}
@@ -9173,7 +9173,7 @@ window.__ModuleLoader__.load({
9173
9173
  }
9174
9174
  //#endregion
9175
9175
  //#region src/version.js
9176
- const PACKAGE_VERSION = "2.7.0";
9176
+ const PACKAGE_VERSION = "2.7.1";
9177
9177
  //#endregion
9178
9178
  //#region src/client-recovery.js
9179
9179
  async function recoveryCall(rpc, endpoint, payload = {}, timeoutMs = 1e4) {
@@ -9444,6 +9444,11 @@ window.__ModuleLoader__.load({
9444
9444
  const ForwardRef = /*#__PURE__*/ react.forwardRef(BoltIcon);
9445
9445
  //#endregion
9446
9446
  //#region src/client-model-select.jsx
9447
+ const MEASURE_STYLE = {
9448
+ visibility: "hidden",
9449
+ left: 0,
9450
+ top: 0
9451
+ };
9447
9452
  function CodexModelSelect({ locked, available, directory, load, select, preference, t }) {
9448
9453
  const state = (0, react.useSyncExternalStore)(directory.subscribe, directory.getSnapshot);
9449
9454
  const preferenceSnapshot = usePreferenceSnapshot(preference);
@@ -9451,6 +9456,8 @@ window.__ModuleLoader__.load({
9451
9456
  const [pane, setPane] = (0, react.useState)("root");
9452
9457
  const [query, setQuery] = (0, react.useState)("");
9453
9458
  const rootRef = (0, react.useRef)(null);
9459
+ const menuRef = (0, react.useRef)(null);
9460
+ const [menuPos, setMenuPos] = (0, react.useState)(null);
9454
9461
  const triggerRef = (0, react.useRef)(null);
9455
9462
  const id = (0, react.useId)();
9456
9463
  const choices = (0, react.useMemo)(() => state.groups.flatMap((group) => group.models.map((model) => ({
@@ -9534,7 +9541,7 @@ window.__ModuleLoader__.load({
9534
9541
  (0, react.useEffect)(() => {
9535
9542
  if (!open) return void 0;
9536
9543
  const closeOutside = (event) => {
9537
- if (!rootRef.current?.contains(event.target)) {
9544
+ if (!rootRef.current?.contains(event.target) && !menuRef.current?.contains(event.target)) {
9538
9545
  setOpen(false);
9539
9546
  setPane("root");
9540
9547
  setQuery("");
@@ -9543,6 +9550,39 @@ window.__ModuleLoader__.load({
9543
9550
  document.addEventListener("mousedown", closeOutside);
9544
9551
  return () => document.removeEventListener("mousedown", closeOutside);
9545
9552
  }, [open]);
9553
+ (0, react.useLayoutEffect)(() => {
9554
+ if (!open) {
9555
+ setMenuPos(null);
9556
+ return;
9557
+ }
9558
+ const place = () => {
9559
+ const rect = triggerRef.current?.getBoundingClientRect();
9560
+ if (rect === void 0) return;
9561
+ const margin = 12;
9562
+ const width = menuRef.current?.offsetWidth ?? 0;
9563
+ const height = menuRef.current?.offsetHeight ?? 0;
9564
+ let left = rect.right - width;
9565
+ let top = rect.top - 8 - height;
9566
+ if (width > 0) left = Math.min(Math.max(left, margin), window.innerWidth - width - margin);
9567
+ if (height > 0) top = Math.min(Math.max(top, margin), window.innerHeight - height - margin);
9568
+ setMenuPos({
9569
+ left,
9570
+ top
9571
+ });
9572
+ };
9573
+ place();
9574
+ window.addEventListener("scroll", place, true);
9575
+ window.addEventListener("resize", place);
9576
+ return () => {
9577
+ window.removeEventListener("scroll", place, true);
9578
+ window.removeEventListener("resize", place);
9579
+ };
9580
+ }, [
9581
+ open,
9582
+ pane,
9583
+ state,
9584
+ query
9585
+ ]);
9546
9586
  (0, react.useEffect)(() => {
9547
9587
  if (pane !== "model") setQuery("");
9548
9588
  }, [pane]);
@@ -9616,10 +9656,10 @@ window.__ModuleLoader__.load({
9616
9656
  type: "button",
9617
9657
  role: "menuitem",
9618
9658
  className: "codexModelSelectCell",
9619
- "data-open": pane === target,
9620
- "aria-haspopup": "menu",
9621
- "aria-expanded": pane === target,
9622
- onClick: () => setPane((current) => current === target ? "root" : target),
9659
+ onClick: () => {
9660
+ setQuery("");
9661
+ setPane(target);
9662
+ },
9623
9663
  children: [
9624
9664
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9625
9665
  className: "codexModelSelectCellLabel",
@@ -9632,141 +9672,147 @@ window.__ModuleLoader__.load({
9632
9672
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronRightOutline14, { className: "codexModelSelectCellChevron" })
9633
9673
  ]
9634
9674
  });
9635
- let submenu = null;
9636
- if (pane === "model") submenu = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9637
- className: "codexModelSelectSubmenu codexModelSelectModelMenu",
9638
- role: "menu",
9639
- "aria-label": t("modelLabel"),
9640
- children: [
9641
- state.status === "loading" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9642
- className: "codexModelSelectStatus",
9643
- children: t("modelsLoading")
9644
- }) : null,
9645
- state.error === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9646
- className: "codexModelSelectError",
9647
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: fill(t("modelFailed"), { value: state.error }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
9648
- className: "codexModelSelectRetry",
9649
- type: "button",
9650
- onClick: load,
9651
- children: t("modelRetry")
9652
- })]
9653
- }),
9654
- state.failures.map((failure) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9655
- className: "codexModelSelectWarning",
9656
- children: fill(t("groupFailed"), {
9657
- name: failure.name,
9658
- value: failure.message
9659
- })
9660
- }, failure.id)),
9661
- searchable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
9675
+ const group = (key, label, children) => MenuGroup === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
9676
+ role: "group",
9677
+ "aria-label": label,
9678
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9679
+ className: "codexModelSelectGroupTitle",
9680
+ children: label
9681
+ }), children]
9682
+ }, key) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuGroup, {
9683
+ label,
9684
+ children
9685
+ }, key);
9686
+ let content = null;
9687
+ if (pane === "root") content = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
9688
+ cell("model", t("modelLabel"), modelLabel),
9689
+ reasoning === void 0 ? null : cell("effort", t("effortLabel"), effortLabel),
9690
+ (speedSupported || ultrafastSupported) && cell("speed", t("speedTitle"), t(speedKey)),
9691
+ verbositySupported && cell("verbosity", t("verbosityTitle"), verbosityLabel)
9692
+ ] });
9693
+ else if (pane === "model") content = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
9694
+ searchable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9695
+ className: "codexModelSelectSearchRow",
9696
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Input, {
9662
9697
  className: "codexModelSelectSearch",
9663
- type: "search",
9698
+ type: "text",
9699
+ role: "searchbox",
9664
9700
  value: query,
9665
9701
  autoFocus: true,
9666
9702
  placeholder: t("modelSearch"),
9667
9703
  "aria-label": t("modelSearch"),
9668
9704
  onChange: (event) => setQuery(event.target.value)
9669
- }) : null,
9670
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9671
- className: "codexModelSelectGroups scrollable",
9672
- children: shownGroups.map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
9673
- className: "codexModelSelectGroup",
9674
- role: "group",
9675
- "aria-labelledby": `${id}-${group.id}`,
9676
- children: [
9677
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9678
- className: "codexModelSelectGroupTitle",
9679
- id: `${id}-${group.id}`,
9680
- children: group.name
9681
- }),
9682
- group.allHidden === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9683
- className: "codexModelSelectEmpty",
9684
- children: t("modelsHidden")
9685
- }) : null,
9686
- group.models.map((model) => option({
9687
- key: model.id,
9688
- label: model.name,
9689
- description: model.description,
9690
- selected: state.current?.provider === group.id && state.current.model === model.id,
9691
- disabled: busy,
9692
- onClick: () => chooseModel({
9693
- provider: group.id,
9694
- model: model.id
9695
- })
9696
- }))
9697
- ]
9698
- }, group.id))
9699
- }),
9700
- state.status === "ready" && visibleGroups.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9701
- className: "codexModelSelectEmpty",
9702
- children: t(choices.length === 0 ? "modelsEmpty" : "modelsHidden")
9703
- }) : null,
9704
- state.status === "ready" && visibleGroups.length > 0 && shownGroups.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9705
+ })
9706
+ }) : null,
9707
+ state.status === "loading" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9708
+ className: "codexModelSelectStatus",
9709
+ children: t("modelsLoading")
9710
+ }) : null,
9711
+ state.error === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9712
+ className: "codexModelSelectError",
9713
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: fill(t("modelFailed"), { value: state.error }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
9714
+ className: "codexModelSelectRetry",
9715
+ type: "button",
9716
+ onClick: load,
9717
+ children: t("modelRetry")
9718
+ })]
9719
+ }),
9720
+ state.failures.map((failure) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9721
+ className: "codexModelSelectWarning",
9722
+ children: fill(t("groupFailed"), {
9723
+ name: failure.name,
9724
+ value: failure.message
9725
+ })
9726
+ }, failure.id)),
9727
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9728
+ className: "codexModelSelectGroups scrollable",
9729
+ role: "menu",
9730
+ "aria-label": t("modelLabel"),
9731
+ children: shownGroups.map((entry) => group(entry.id, entry.name, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [entry.allHidden === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9705
9732
  className: "codexModelSelectEmpty",
9706
- children: t("modelNoMatch")
9707
- }) : null
9708
- ]
9709
- });
9710
- else if (pane === "effort") submenu = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9711
- className: "codexModelSelectSubmenu",
9712
- role: "menu",
9713
- "aria-label": t("effortLabel"),
9714
- children: effortChoices.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9733
+ children: t("modelsHidden")
9734
+ }) : null, entry.models.map((model) => option({
9735
+ key: model.id,
9736
+ label: model.name,
9737
+ selected: state.current?.provider === entry.id && state.current.model === model.id,
9738
+ disabled: busy,
9739
+ onClick: () => chooseModel({
9740
+ provider: entry.id,
9741
+ model: model.id
9742
+ })
9743
+ }))] })))
9744
+ }),
9745
+ state.status === "ready" && visibleGroups.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9715
9746
  className: "codexModelSelectEmpty",
9716
- children: t("effortsEmpty")
9717
- }) : effortChoices.map((level) => option({
9718
- key: level.key,
9719
- label: level.label,
9720
- description: level.description,
9721
- selected: effectiveEffort === level.effort,
9722
- disabled: busy,
9723
- onClick: () => chooseEffort(level.effort)
9724
- }))
9725
- });
9726
- else if (pane === "speed") submenu = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9727
- className: "codexModelSelectSubmenu",
9728
- role: "menu",
9729
- "aria-label": t("speedTitle"),
9730
- children: [
9731
- option({
9732
- key: SPEED_MODE_STANDARD,
9733
- label: t("speedStandard"),
9734
- description: t("speedStandardHint"),
9735
- selected: !fast,
9736
- disabled: !speedWritable,
9737
- onClick: () => chooseSpeed(SPEED_MODE_STANDARD)
9738
- }),
9739
- speedSupported && option({
9740
- key: "fast",
9741
- label: t("speedFast"),
9742
- description: t(state.current?.model === "gpt-6-astra" ? "speedFastAstraHint" : "speedFastHint"),
9743
- selected: fast && !ultrafast,
9744
- disabled: !speedWritable,
9745
- onClick: () => chooseSpeed("fast")
9746
- }),
9747
- ultrafastSupported && option({
9748
- key: "ultrafast",
9749
- label: t("speedUltrafast"),
9750
- description: t("speedUltrafastHint"),
9751
- selected: ultrafast,
9752
- disabled: !speedWritable,
9753
- onClick: () => chooseSpeed("ultrafast")
9754
- })
9755
- ]
9756
- });
9757
- else if (pane === "verbosity") submenu = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9758
- className: "codexModelSelectSubmenu",
9759
- role: "menu",
9760
- "aria-label": t("verbosityTitle"),
9761
- children: verbosityItems.map((item) => option({
9762
- key: item.id,
9763
- label: item.label,
9764
- description: item.description,
9765
- selected: preferenceSnapshot.outputVerbosity === item.id,
9766
- disabled: !verbosityWritable,
9767
- onClick: () => chooseVerbosity(item.id)
9768
- }))
9769
- });
9747
+ children: t(choices.length === 0 ? "modelsEmpty" : "modelsHidden")
9748
+ }) : null,
9749
+ state.status === "ready" && visibleGroups.length > 0 && shownGroups.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9750
+ className: "codexModelSelectEmpty",
9751
+ children: t("modelNoMatch")
9752
+ }) : null
9753
+ ] });
9754
+ else if (pane === "effort") content = effortChoices.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9755
+ className: "codexModelSelectEmpty",
9756
+ children: t("effortsEmpty")
9757
+ }) : effortChoices.map((level) => option({
9758
+ key: level.key,
9759
+ label: level.label,
9760
+ description: level.description,
9761
+ selected: effectiveEffort === level.effort,
9762
+ disabled: busy,
9763
+ onClick: () => chooseEffort(level.effort)
9764
+ }));
9765
+ else if (pane === "speed") content = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
9766
+ option({
9767
+ key: SPEED_MODE_STANDARD,
9768
+ label: t("speedStandard"),
9769
+ description: t("speedStandardHint"),
9770
+ selected: !fast,
9771
+ disabled: !speedWritable,
9772
+ onClick: () => chooseSpeed(SPEED_MODE_STANDARD)
9773
+ }),
9774
+ speedSupported && option({
9775
+ key: "fast",
9776
+ label: t("speedFast"),
9777
+ description: t(state.current?.model === "gpt-6-astra" ? "speedFastAstraHint" : "speedFastHint"),
9778
+ selected: fast && !ultrafast,
9779
+ disabled: !speedWritable,
9780
+ onClick: () => chooseSpeed("fast")
9781
+ }),
9782
+ ultrafastSupported && option({
9783
+ key: "ultrafast",
9784
+ label: t("speedUltrafast"),
9785
+ description: t("speedUltrafastHint"),
9786
+ selected: ultrafast,
9787
+ disabled: !speedWritable,
9788
+ onClick: () => chooseSpeed("ultrafast")
9789
+ })
9790
+ ] });
9791
+ else if (pane === "verbosity") content = verbosityItems.map((item) => option({
9792
+ key: item.id,
9793
+ label: item.label,
9794
+ description: item.description,
9795
+ selected: preferenceSnapshot.outputVerbosity === item.id,
9796
+ disabled: !verbosityWritable,
9797
+ onClick: () => chooseVerbosity(item.id)
9798
+ }));
9799
+ const menu = open ? (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuSurface ?? "div", {
9800
+ ref: menuRef,
9801
+ id: `${id}-menu`,
9802
+ className: "codexModelSelectMenu",
9803
+ style: menuPos ?? MEASURE_STYLE,
9804
+ role: pane === "model" ? "group" : "menu",
9805
+ "aria-label": t("modelMenuAria"),
9806
+ "aria-busy": state.status === "loading" || busy,
9807
+ onKeyDown: (event) => {
9808
+ if (event.key !== "Escape") return;
9809
+ event.preventDefault();
9810
+ event.stopPropagation();
9811
+ if (pane === "root") close(true);
9812
+ else setPane("root");
9813
+ },
9814
+ children: content
9815
+ }), document.body) : null;
9770
9816
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9771
9817
  className: "codexModelSelect",
9772
9818
  ref: rootRef,
@@ -9802,20 +9848,7 @@ window.__ModuleLoader__.load({
9802
9848
  }),
9803
9849
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronDownOutline14, { className: "codexModelSelectChevron" })
9804
9850
  ]
9805
- }), open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9806
- className: "codexModelSelectMenu",
9807
- id: `${id}-menu`,
9808
- role: "menu",
9809
- "aria-label": t("modelMenuAria"),
9810
- "aria-busy": state.status === "loading" || busy,
9811
- children: [
9812
- cell("model", t("modelLabel"), modelLabel),
9813
- reasoning === void 0 ? null : cell("effort", t("effortLabel"), effortLabel),
9814
- (speedSupported || ultrafastSupported) && cell("speed", t("speedTitle"), t(speedKey)),
9815
- verbositySupported && cell("verbosity", t("verbosityTitle"), verbosityLabel),
9816
- submenu
9817
- ]
9818
- }) : null]
9851
+ }), menu]
9819
9852
  });
9820
9853
  }
9821
9854
  //#endregion
package/lib/index.js CHANGED
@@ -2088,7 +2088,7 @@ function inheritedOriginalImageRef(session, assetId) {
2088
2088
  }
2089
2089
  //#endregion
2090
2090
  //#region src/version.js
2091
- const PACKAGE_VERSION = "2.7.0";
2091
+ const PACKAGE_VERSION = "2.7.1";
2092
2092
  const USER_AGENT = `dsh-codex-subscription/${PACKAGE_VERSION}`;
2093
2093
  //#endregion
2094
2094
  //#region src/http-failure.js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-codex-subscription",
3
- "version": "2.7.0",
3
+ "version": "2.7.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",