dsh-codex-subscription 2.1.3 → 2.1.5-beta.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
@@ -22,20 +22,15 @@ No OpenAI API key or Codex CLI. Models, search, quota, and image generation stay
22
22
  <img src="docs/assets/codex-subscription-overview-en.webp" width="900" alt="Use ChatGPT and Codex subscriptions in DeepSeek Harness: sign in without an API key, choose models and view remaining quota">
23
23
  </p>
24
24
 
25
- ## Three-step start
26
-
27
- 1. **Install the plugin.** In newer DSH, open **Plugins → Add plugin** and enter `dsh-codex-subscription`. To select a candidate, enter `package@version`, for example `dsh-codex-subscription@2.1.3-beta.1`. This field does not accept a full terminal command.
28
-
29
- For older DSH or terminal use, run:
25
+ Compatible with the settings and UI changes in DSH `0.1.7-alpha.1`, while retaining support for previously supported versions.
30
26
 
31
- ```sh
32
- dsh plugin --profile web add dsh-codex-subscription
33
- ```
27
+ ## Three-step start
34
28
 
29
+ 1. **Install the plugin.** Open **Plugins → Add plugin**, enter `dsh-codex-subscription` in **Package name or address**, and click **Install**.
35
30
  2. **Sign in.** Follow the installation result; save your work and restart only if requested. Open **Settings -> Codex**, and choose browser sign-in. No Codex CLI and no pasted token are required.
36
31
  3. **Use Codex.** Select a Codex model. Quota, subscription search, image generation, and Fast mode remain inside DSH.
37
32
 
38
- DSH-Portable exposes the same standard plugin command, so the command above also applies there. See below for the complete official npm, update, and uninstall routes.
33
+ See below for detailed installation steps, terminal commands, updates, and removal.
39
34
 
40
35
  ## Why this plugin
41
36
 
@@ -43,7 +38,7 @@ DSH-Portable exposes the same standard plugin command, so the command above also
43
38
  | --- | --- |
44
39
  | **Subscription models** | Sign in to ChatGPT and use Codex without an OpenAI API key or Codex CLI |
45
40
  | **Recoverable and diagnosable** | Sign-in state reconciles automatically; failed reads can be retried in place, while timeouts and stale account responses cannot overwrite current state; Settings can create a support report without credentials or account identifiers |
46
- | **Visible quota** | Keep backend-provided standard Codex, Spark, and other limits separate |
41
+ | **Visible quota** | Keep backend-provided standard Codex, Spark, and other limits separate, with reset times |
47
42
  | **Composer quota** | Choose a compact percentage, progress bar, Beta runway forecast, or no inline display |
48
43
  | **Safe quota reset** | See each reset credit separately and deliberately try one with a cooldown and acknowledgement |
49
44
  | **Subscription search** | Explicitly route search globally through DSH default search or the signed-in Codex subscription |
@@ -71,70 +66,48 @@ This plugin supports the latest DeepSeek Harness release recorded in its package
71
66
 
72
67
  ## Install
73
68
 
74
- ### Standard DSH command
69
+ ### Install from the Plugins page (recommended)
75
70
 
76
- ```sh
77
- dsh plugin --profile web add dsh-codex-subscription
78
- ```
79
-
80
- DSH owns target selection, profile locking, dependency resolution, and bundle activation; this is the plugin's only installation path.
71
+ 1. Open **Plugins → Add plugin** in DSH.
72
+ 2. Paste this package name into the **Package name or address** field:
81
73
 
82
- ### Headless
74
+ ```text
75
+ dsh-codex-subscription
76
+ ```
83
77
 
84
- After signing in and selecting a Codex model in Web once, install the same plugin in DSH's standard Headless profile:
78
+ 3. Click **Install** and wait for completion. Follow the page instructions; save your work before restarting if requested.
79
+ 4. Open **Settings → Codex**, sign in to ChatGPT, then select a Codex model in your conversation.
85
80
 
86
- ```sh
87
- dsh plugin --profile headless add dsh-codex-subscription
88
- dsh --profile headless "Reply with only the word: ok"
89
- ```
81
+ The unversioned package name installs the latest stable release. To select a version, enter `dsh-codex-subscription@2.1.4`; for a beta, use the complete version from its release notes. Enter only the package name here, not a terminal command. This plugin can be installed using its npm package name; no GitHub URL or local directory is needed.
90
82
 
91
83
  <details>
92
- <summary>Official npm route (Node.js installed)</summary>
93
-
94
- The official `npx @deepseek-ai/dsh web` command does not create a global `dsh` command. Keep the full `npx` prefix when installing the plugin:
84
+ <summary>Terminal installation (with an existing dsh command)</summary>
95
85
 
96
86
  ```sh
97
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web add dsh-codex-subscription
98
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web list dsh-codex-subscription --depth 0
99
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 --profile web --dump-config
87
+ dsh plugin --profile web add dsh-codex-subscription
100
88
  ```
101
89
 
90
+ Follow the restart instructions, then sign in under **Settings → Codex**. Both the Plugins page and the terminal use DSH's installation management.
91
+
102
92
  </details>
103
93
 
104
94
  <details>
105
- <summary>An existing <code>dsh</code> command</summary>
95
+ <summary>Headless tasks</summary>
96
+
97
+ After signing in and selecting a Codex model in Web, install the same plugin in the Headless profile:
106
98
 
107
99
  ```sh
108
- dsh plugin --profile web add dsh-codex-subscription
109
- dsh plugin --profile web list dsh-codex-subscription --depth 0
110
- dsh --profile web --dump-config
100
+ dsh plugin --profile headless add dsh-codex-subscription
101
+ dsh --profile headless "Reply with only the word: ok"
111
102
  ```
112
103
 
113
- The plugin list should contain one `dsh-codex-subscription`, and the config should contain one `codex-subscription` entry.
114
-
115
104
  </details>
116
105
 
117
- Restart DSH manually after installation, then:
106
+ ## Feature details
118
107
 
119
- 1. Open **Settings -> Codex**.
120
- 2. Sign in with a ChatGPT account that has Codex access.
121
- 3. Choose a search source.
122
- 4. Select a Codex model.
123
-
124
- ## Features
125
-
126
- - ChatGPT OAuth sign-in with credentials kept on the host; accounts are identified by a privacy-masked email that can be clicked to reveal, and can be manually added, switched, or removed without automatic rotation or quota pooling;
127
- - Codex models and Beta image generation/editing directly inside DSH conversations;
128
- - A clear global choice between DSH default search and Codex subscription search; it applies to every model and session rather than following the selected model;
129
- - Actual backend-provided quota, reset time, and freshness;
130
- - Separate standard Codex, Codex-Spark, Credits, and other independent limits;
131
- - One row per available quota reset with its disclosed name and expiry, plus deliberate early redemption, layered confirmation, and no automatic retry;
132
- - Optional percentage, progress bar, or Beta runway estimate for the selected Codex model (off by default);
133
- - Standard or Fast mode for supported Codex models directly in the composer;
134
- - Standard, Extended, and per-model Custom context windows; Custom accepts a full numeric token count, stays within each audited model capacity, and feeds DSH's native agent compaction policy;
135
- - A copyable support report and direct feedback link in Settings; the report includes bounded request stages, HTTP/transport classes, elapsed ranges, and route source types while excluding OAuth credentials, account identifiers, and authorization timestamps;
136
- - Visible errors when subscription routing is unavailable, with no silent paid fallback.
108
+ ### Add instructions while a task is running
137
109
 
110
+ Use DSH’s native message queue: messages sent during generation can wait for the next turn. Where the host offers interjection, its shortcut delivers queued input at the next step of the current turn. This does not immediately rewrite a response already being generated.
138
111
 
139
112
  ### GPT-Reserve (Experimental)
140
113
 
@@ -250,7 +223,7 @@ With a supported Codex model selected, open the composer's model menu to choose
250
223
  Standard adds no icon; only Fast shows a lightning icon before the model name. Spark does not show the speed entry. Fast mode increases speed and uses more Credits;
251
224
  see the [OpenAI Codex Speed documentation](https://learn.chatgpt.com/docs/agent-configuration/speed) for the current rules.
252
225
 
253
- ### Advanced experiments (2.1.1 Beta)
226
+ ### Advanced experiments
254
227
 
255
228
  Opt in under **Advanced & diagnostics**. SSE and DSH subtasks remain the defaults:
256
229
 
@@ -267,19 +240,20 @@ In **Settings → Codex → Advanced → Independent subtasks**, click **Install
267
240
 
268
241
  ![Optional component management](docs/assets/settings-runtime-current-en.png)
269
242
 
270
- For older hosts without the management interface, run this in the target DSH environment, then restart:
243
+ Prefer **Install component** above: the plugin selects a verified component version. The current stable release, **2.1.4**, uses `0.1.5-rc.2`. Do not omit the version or substitute `@next`. `2.1.5-beta.1` installs `0.1.5-rc.3` by default and remains compatible with an existing rc.2 installation.
244
+
245
+ <details>
246
+ <summary>Manual installation on older hosts and offline preparation</summary>
247
+
248
+ Enter `@deepseek-ai/dsh-subagent-codex@0.1.5-rc.2` in the plugin installer, or run:
271
249
 
272
250
  ```sh
273
251
  dsh plugin --profile web add @deepseek-ai/dsh-subagent-codex@0.1.5-rc.2
274
252
  ```
275
253
 
276
- In the plugin installation UI, enter only `@deepseek-ai/dsh-subagent-codex@0.1.5-rc.2`, not the full command. Select Codex in advanced settings after preparation. Missing or failed preparation does not block subscription chat or the DSH backend. Shared-context subtasks remain in DSH.
277
-
278
- For offline preparation, install and verify beforehand on the target operating system and architecture, retaining the complete profile dependencies when moving it. The subscription archive or Codex wrapper alone is insufficient without the platform binary. First-time installation cannot complete offline unless dependencies are already prepared. Existing runtime checks and startup do not download anything; model requests still require connectivity. Do not use `--force` to install foreign-platform optional packages.
254
+ Use the same profile as the subscription plugin and restart afterwards. Offline preparation requires a complete runtime installed and verified on the target OS and architecture; copying only the subscription plugin or Codex launcher is insufficient. Model requests still need connectivity.
279
255
 
280
- **Upgrading an existing installation:** if you use Codex subtasks, run the preparation command before upgrading this plugin to retain the runtime explicitly in the same profile. A runtime only installed transitively by an older version may be removed during dependency reconciliation. The same command repairs an already-upgraded installation; restart afterwards.
281
-
282
- The runtime version is pinned separately; subscription updates do not silently upgrade it. This integration uses the official provider package-local CLI, never searches PATH or desktop-private runtimes, and removes the component only after an explicit uninstall request. Shared package caches are not deleted.
256
+ </details>
283
257
 
284
258
  ### When you no longer need it
285
259
 
@@ -299,46 +273,26 @@ Uninstalling does not clear shared package caches or guarantee a fixed amount of
299
273
 
300
274
  ## Update and uninstall
301
275
 
302
- ### Update and verify
303
-
304
- ```sh
305
- dsh plugin --profile web update dsh-codex-subscription
306
- dsh plugin --profile web list dsh-codex-subscription --depth 0
307
- dsh --profile web --dump-config
308
- ```
309
-
310
- ### Uninstall
311
-
312
- Run this only when you want to remove the plugin:
313
-
314
- ```sh
315
- dsh plugin --profile web remove dsh-codex-subscription
316
- ```
317
-
318
- These operations preserve the DSH profile, other plugins, and saved sign-in.
276
+ Find this plugin on the DSH **Plugins** page and use its update or uninstall action. Follow any restart instructions. Uninstalling this plugin does not remove other plugins.
319
277
 
320
278
  <details>
321
- <summary>Official npm fallback</summary>
322
-
323
- ### Update and verify
279
+ <summary>Terminal commands</summary>
324
280
 
325
281
  ```sh
326
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web update dsh-codex-subscription
327
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web list dsh-codex-subscription --depth 0
328
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 --profile web --dump-config
282
+ dsh plugin --profile web update dsh-codex-subscription
329
283
  ```
330
284
 
331
- ### Uninstall
285
+ Run only when you want to uninstall:
332
286
 
333
287
  ```sh
334
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web remove dsh-codex-subscription
288
+ dsh plugin --profile web remove dsh-codex-subscription
335
289
  ```
336
290
 
337
291
  </details>
338
292
 
339
293
  ## Troubleshooting
340
294
 
341
- - **`dsh` is not recognized:** the official npm route does not create a global `dsh` command; use the complete `npx -y @deepseek-ai/dsh@0.1.5-rc.2 ...` command above;
295
+ - **`dsh` is not recognized:** install from the DSH Plugins page; no terminal setup is needed.
342
296
  - **More than one DSH exists:** run the standard command from the intended DSH environment so that product selects the corresponding profile;
343
297
  - **Setup still fails:** confirm the command is running in the intended DSH environment. Do not delete the profile or change the system PATH to force an install.
344
298
  - **Need to report a problem:** generate a **Support diagnostics** report at the bottom of Settings, then open the [bug report form](https://github.com/WSL043/dsh-codex-subscription/issues/new?template=install-problem.yml). The report includes the OS/runtime, bounded sign-in phase, and safe request-failure categories, but excludes credentials, account identifiers, raw responses, and full logs. Paste it into the required diagnostics field; never attach sign-in URLs, authorization codes, or browser callback addresses.
package/README.md CHANGED
@@ -23,20 +23,15 @@
23
23
  <img src="docs/assets/codex-subscription-overview.webp" width="900" alt="在 DeepSeek Harness 登录 ChatGPT 并使用 Codex 订阅:无需 API Key,支持模型选择和剩余额度显示">
24
24
  </p>
25
25
 
26
- ## 三步开始
27
-
28
- 1. **安装插件**:在新版 DSH 的 **插件 → 添加插件** 中填写 `dsh-codex-subscription`;指定候选版本时填写完整的 `包名@版本`,例如 `dsh-codex-subscription@2.1.3-beta.1`。这个输入框不接受整条终端命令。
29
-
30
- 旧版 DSH 或偏好终端操作时,才在终端运行:
26
+ 已适配 DSH `0.1.7-alpha.1` 的设置保存与界面接口,同时保留已支持版本的兼容。
31
27
 
32
- ```sh
33
- dsh plugin --profile web add dsh-codex-subscription
34
- ```
28
+ ## 三步开始
35
29
 
30
+ 1. **安装插件**:打开 **插件 → 添加插件**,在 **包名或地址** 中填写 `dsh-codex-subscription`,点击 **安装**。
36
31
  2. **登录订阅**:按安装结果提示操作;若提示需要重启,先保存工作再重启。打开 **设置 -> Codex 订阅**,点击浏览器登录。无需 Codex CLI,也不要粘贴 token。
37
32
  3. **开始使用**:在模型选择器中选择 Codex;额度、订阅搜索、图片生成和高速模式都在 DSH 内使用。
38
33
 
39
- DSH-Portable 也提供相同的标准插件命令,因此同样使用上面的命令。完整的官方 npm、更新和卸载方式见下文。
34
+ 详细安装步骤、终端方式以及更新与卸载说明见下文。
40
35
 
41
36
  ## 核心优势
42
37
 
@@ -44,7 +39,7 @@ DSH-Portable 也提供相同的标准插件命令,因此同样使用上面的
44
39
  | --- | --- |
45
40
  | **订阅模型直连** | 登录 ChatGPT 后直接使用 Codex,不需要 OpenAI API Key 或 Codex CLI |
46
41
  | **可恢复、可诊断** | 登录状态会自动对账;读取失败时可在原处重试,超时和旧账号响应不会覆盖当前状态;设置页可生成不含凭据和账号标识的支持报告 |
47
- | **额度可见** | 普通 Codex、Spark 等服务端实际返回的额度分开显示 |
42
+ | **额度可见** | 普通 Codex、Spark 等服务端实际返回的额度分开显示,并显示重置时间 |
48
43
  | **输入框额度** | 可选择紧凑百分比、进度条、Beta 续航预测或关闭显示 |
49
44
  | **安全额度重置** | 每张重置卡单独显示,并通过冷静期和知情确认主动尝试重置 |
50
45
  | **订阅搜索** | 可将全部模型的搜索明确路由到 DSH 默认搜索或已登录的 Codex 订阅 |
@@ -72,70 +67,48 @@ DSH-Portable 也提供相同的标准插件命令,因此同样使用上面的
72
67
 
73
68
  ## 安装
74
69
 
75
- ### DSH 标准命令
70
+ ### 在插件页面安装(推荐)
76
71
 
77
- ```sh
78
- dsh plugin --profile web add dsh-codex-subscription
79
- ```
80
-
81
- 目标选择、profile 锁、依赖解析和 bundle 激活均由 DSH 负责;这是插件唯一的安装路径。
72
+ 1. 打开 DSH 的 **插件 → 添加插件**。
73
+ 2. 在 **包名或地址** 输入框中粘贴下面的包名:
82
74
 
83
- ### Headless
75
+ ```text
76
+ dsh-codex-subscription
77
+ ```
84
78
 
85
- 先在 Web 中完成登录并选择一次 Codex 模型,再把同一个插件安装到 DSH 的标准 Headless profile:
79
+ 3. 点击 **安装**,等待安装完成;按页面提示操作,需要重启时先保存工作。
80
+ 4. 打开 **设置 → Codex 订阅**,登录 ChatGPT,然后在会话中选择 Codex 模型。
86
81
 
87
- ```sh
88
- dsh plugin --profile headless add dsh-codex-subscription
89
- dsh --profile headless "只回复:ok"
90
- ```
82
+ 包名不带版本号时安装最新正式版。指定版本时填写 `dsh-codex-subscription@2.1.4`;测试版则使用对应发布说明中的完整版本号。此处只填包名,不要粘贴整条终端命令。安装本插件使用上面的 npm 包名即可,无需填写 GitHub 地址或本地目录。
91
83
 
92
84
  <details>
93
- <summary>官方 npm 方式(已安装 Node.js)</summary>
94
-
95
- 官方的 `npx @deepseek-ai/dsh web` 不会创建全局 `dsh` 命令,因此安装插件时也要保留完整的 `npx` 前缀:
85
+ <summary>终端安装(已能运行 dsh 命令)</summary>
96
86
 
97
87
  ```sh
98
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web add dsh-codex-subscription
99
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web list dsh-codex-subscription --depth 0
100
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 --profile web --dump-config
88
+ dsh plugin --profile web add dsh-codex-subscription
101
89
  ```
102
90
 
91
+ 安装完成后按提示重启 DSH,再到 **设置 → Codex 订阅** 登录。插件页面和终端均由 DSH 管理安装。
92
+
103
93
  </details>
104
94
 
105
95
  <details>
106
- <summary>已经能运行 <code>dsh</code></summary>
96
+ <summary>Headless 任务</summary>
97
+
98
+ 先在 Web 中完成登录并选择一次 Codex 模型,再把同一个插件安装到 Headless profile:
107
99
 
108
100
  ```sh
109
- dsh plugin --profile web add dsh-codex-subscription
110
- dsh plugin --profile web list dsh-codex-subscription --depth 0
111
- dsh --profile web --dump-config
101
+ dsh plugin --profile headless add dsh-codex-subscription
102
+ dsh --profile headless "只回复:ok"
112
103
  ```
113
104
 
114
- 安装列表中应只有一个 `dsh-codex-subscription`,配置中应只有一个 `codex-subscription` 条目。
115
-
116
105
  </details>
117
106
 
118
- 安装完成后手动重启 DSH,然后:
107
+ ## 功能说明
119
108
 
120
- 1. 打开 **设置 -> Codex 订阅**;
121
- 2. 登录具有 Codex 使用资格的 ChatGPT 账户;
122
- 3. 选择搜索来源;
123
- 4. 在模型选择器中选择 Codex 模型。
124
-
125
- ## 功能
126
-
127
- - ChatGPT OAuth 登录,凭据保留在本机;账号以默认隐藏部分字符的邮箱区分,点击可切换完整显示;可手动添加、切换和移除多个账号,不会自动轮换或合并额度;
128
- - Codex 模型和 Beta 图片生成与编辑直接出现在 DSH 会话中;
129
- - 搜索来源是全局设置,可在 DSH 默认搜索与 Codex 订阅搜索之间切换;它对所有模型和会话生效,不会随当前模型自动切换;
130
- - 设置页显示服务端返回的额度、重置时间和更新时间;
131
- - 普通 Codex、Codex-Spark、Credits 等独立额度分开显示;
132
- - 每张可用重置卡单独显示名称和到期时间,也允许在额度未完全用尽时主动尝试,并经过分层确认且不会自动重试;
133
- - 输入框可用百分比、进度条或可选的 Beta 续航预测显示当前 Codex 模型的剩余额度(默认关闭);
134
- - 输入框可为支持的 Codex 模型切换标准或高速模式;
135
- - 上下文窗口提供标准、扩展和逐模型自定义;自定义直接填写完整 Token 数值,并在已审核的模型容量内交给 DSH 原生 Agent 压缩策略处理;
136
- - 设置页可生成并复制无敏感信息的支持诊断,并直接打开反馈入口;报告包含有限的请求阶段、HTTP/网络分类、耗时区间和路由来源类型,但不包含 OAuth 凭据、账号标识或授权时间;
137
- - 订阅路由不可用时明确报错,不会静默切换到其他付费路由。
109
+ ### 执行中补充指令
138
110
 
111
+ 沿用 DSH 原生消息队列:生成中发送消息可排队到下一轮;界面提供插话入口时,可用其快捷键将排队内容交给当前轮的下一步处理。插话不是立即改写正在生成的响应。
139
112
 
140
113
  ### GPT-Reserve(实验性)
141
114
 
@@ -249,7 +222,7 @@ ChatGPT 返回可用重置卡时,设置页会把每张卡分别显示为紧凑
249
222
  只有高速模式会在模型名称左侧显示闪电;Spark 不显示速度入口。高速模式会提高速度,也会消耗更多 Credits;具体规则见
250
223
  [OpenAI Codex Speed 文档](https://learn.chatgpt.com/docs/agent-configuration/speed)。
251
224
 
252
- ### 高级实验选项(2.1.1 Beta)
225
+ ### 高级实验选项
253
226
 
254
227
  在 **高级与诊断** 中按需开启,默认仍使用 SSE 和 DSH 子任务:
255
228
 
@@ -266,19 +239,20 @@ ChatGPT 返回可用重置卡时,设置页会把每张卡分别显示为紧凑
266
239
 
267
240
  ![可选组件管理实机界面](docs/assets/settings-runtime-current.png)
268
241
 
269
- 旧版宿主没有管理接口时,才在目标 DSH 环境的终端执行,然后重启:
242
+ 优先使用上面的 **安装组件** 按钮,由插件选择已验证的组件版本。当前正式版 **2.1.4** 使用 `0.1.5-rc.2`;请不要省略版本号或自行改用 `@next`。`2.1.5-beta.1` 默认安装 `0.1.5-rc.3`,并继续兼容已安装的 rc.2。
243
+
244
+ <details>
245
+ <summary>旧版宿主手动安装与离线准备</summary>
246
+
247
+ 插件安装页面填写 `@deepseek-ai/dsh-subagent-codex@0.1.5-rc.2`。终端方式:
270
248
 
271
249
  ```sh
272
250
  dsh plugin --profile web add @deepseek-ai/dsh-subagent-codex@0.1.5-rc.2
273
251
  ```
274
252
 
275
- 如果使用插件安装页面,在包名框只填 `@deepseek-ai/dsh-subagent-codex@0.1.5-rc.2`,不要粘贴整条命令。安装到订阅插件所在的同一个 profile。之后在高级设置选择 Codex;共享上下文子任务仍由 DSH 处理。准备失败或尚未准备不影响普通订阅聊天,可继续选择 DSH。
276
-
277
- 离线使用前,应在同系统、同架构的目标环境提前安装并验证运行时,迁移时保留完整的 DSH profile 依赖。只有订阅插件压缩包或 Codex 主包不能代替当前平台的可执行包;未提前准备时,断网无法完成首次安装。已有运行时的检查和启动不需要下载安装,但模型请求本身仍需要联网。不要使用 `--force` 安装其他平台的可选包。
253
+ 安装到订阅插件所在的同一个 profile,完成后重启。离线使用须提前在目标系统与架构上安装并验证完整运行时;只复制订阅插件或 Codex 启动脚本不够。模型请求仍需联网。
278
254
 
279
- **旧版升级**:如果已使用 Codex 独立子任务,请在升级订阅插件前执行上面的准备命令,将运行时显式保留在同一个 profile;仅由旧版间接安装的运行时可能随依赖整理移除。已经升级也可执行同一命令补齐,然后重启。
280
-
281
- 运行时版本单独固定,不会随订阅插件更新而自动下载新 CLI。现阶段沿用官方 provider 的包内 CLI,不自动查找 PATH,也不复用桌面应用的私有 CLI。只有明确点击卸载才移除组件,安装缓存不由插件清理。
255
+ </details>
282
256
 
283
257
  ### 不再使用时
284
258
 
@@ -298,46 +272,26 @@ dsh plugin --profile web remove @deepseek-ai/dsh-subagent-codex
298
272
 
299
273
  ## 更新与卸载
300
274
 
301
- ### 更新并检查
302
-
303
- ```sh
304
- dsh plugin --profile web update dsh-codex-subscription
305
- dsh plugin --profile web list dsh-codex-subscription --depth 0
306
- dsh --profile web --dump-config
307
- ```
308
-
309
- ### 卸载
310
-
311
- 确认需要移除插件后再运行:
312
-
313
- ```sh
314
- dsh plugin --profile web remove dsh-codex-subscription
315
- ```
316
-
317
- 这些操作会保留 DSH profile、其他插件和登录信息。
275
+ 在 DSH **插件** 页面找到本插件,使用更新或卸载操作,完成后按页面提示重启。卸载插件不会删除其他插件。
318
276
 
319
277
  <details>
320
- <summary>官方 npm 备用方式</summary>
321
-
322
- ### 更新并检查
278
+ <summary>终端方式</summary>
323
279
 
324
280
  ```sh
325
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web update dsh-codex-subscription
326
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web list dsh-codex-subscription --depth 0
327
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 --profile web --dump-config
281
+ dsh plugin --profile web update dsh-codex-subscription
328
282
  ```
329
283
 
330
- ### 卸载
284
+ 仅在需要卸载时运行:
331
285
 
332
286
  ```sh
333
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web remove dsh-codex-subscription
287
+ dsh plugin --profile web remove dsh-codex-subscription
334
288
  ```
335
289
 
336
290
  </details>
337
291
 
338
292
  ## 常见问题
339
293
 
340
- - **`dsh` 无法识别**:官方 npm 方式本来就不会创建全局 `dsh` 命令,请使用上面的完整 `npx -y @deepseek-ai/dsh@0.1.5-rc.2 ...` 命令;
294
+ - **`dsh` 无法识别**:直接使用 DSH 的插件页面安装,无需为了安装插件配置终端命令。
341
295
  - **电脑上有多个 DSH**:请从目标 DSH 环境运行标准命令,由该产品自身选择对应 profile;
342
296
  - **安装仍然失败**:确认命令是在目标 DSH 环境中运行,不要删除 profile 或随意修改系统 PATH。
343
297
  - **需要提交问题**:在设置页底部生成“支持诊断”,然后打开[使用问题表单](https://github.com/WSL043/dsh-codex-subscription/issues/new?template=install-problem.yml)。报告包含系统/运行时、有限的登录阶段和安全的请求失败分类,但不含凭据、账号标识、原始响应或完整日志;请粘贴到必填诊断栏,且不要附上登录链接、授权码或浏览器回调地址。
@@ -9,6 +9,8 @@
9
9
  "0.1.5-alpha.1",
10
10
  "0.1.5-alpha.2",
11
11
  "0.1.6-alpha.1",
12
- "0.1.6-alpha.2"
12
+ "0.1.6-alpha.2",
13
+ "0.1.7-alpha.1",
14
+ "0.1.7-alpha.2"
13
15
  ]
14
16
  }
Binary file
package/lib/client.js CHANGED
@@ -31,6 +31,7 @@ window.__ModuleLoader__.load({
31
31
  let react_jsx_runtime = require("react/jsx-runtime");
32
32
  let react_dom = require("react-dom");
33
33
  let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
34
+ _deepseek_ai_dsh_client_ui_primitives = __toESM(_deepseek_ai_dsh_client_ui_primitives, 1);
34
35
  //#region src/sketch-curves.js
35
36
  const cached = /* @__PURE__ */ new WeakMap();
36
37
  const midpoint = (a, b) => ({
@@ -4417,6 +4418,23 @@ window.__ModuleLoader__.load({
4417
4418
  }) });
4418
4419
  }
4419
4420
  //#endregion
4421
+ //#region src/client-primitives.js
4422
+ const Input = _deepseek_ai_dsh_client_ui_primitives.Input;
4423
+ const Button = _deepseek_ai_dsh_client_ui_primitives.Button;
4424
+ const useAnchoredPosition = _deepseek_ai_dsh_client_ui_primitives.useAnchoredPosition;
4425
+ const useDismissOnOutsidePointer = _deepseek_ai_dsh_client_ui_primitives.useDismissOnOutsidePointer;
4426
+ const IconCheckOutline16 = _deepseek_ai_dsh_client_ui_primitives.IconCheckOutline16 ?? _deepseek_ai_dsh_client_ui_primitives.IconCheckOutlineRegular;
4427
+ const IconChevronDownOutline14 = _deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14 ?? _deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular;
4428
+ const IconChevronRightOutline14 = _deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14 ?? _deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular;
4429
+ const Menu = _deepseek_ai_dsh_client_ui_primitives.Menu;
4430
+ const Tooltip = _deepseek_ai_dsh_client_ui_primitives.Tooltip;
4431
+ const IconChevronLeftOutline14 = _deepseek_ai_dsh_client_ui_primitives.IconChevronLeftOutline14 ?? _deepseek_ai_dsh_client_ui_primitives.IconChevronLeftOutlineRegular;
4432
+ const IconCloseOutline16 = _deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16 ?? _deepseek_ai_dsh_client_ui_primitives.IconCloseOutlineRegular;
4433
+ const IconCopyOutline16 = _deepseek_ai_dsh_client_ui_primitives.IconCopyOutline16 ?? _deepseek_ai_dsh_client_ui_primitives.IconCopyOutlineRegular;
4434
+ const IconDownloadOutline16 = _deepseek_ai_dsh_client_ui_primitives.IconDownloadOutline16 ?? _deepseek_ai_dsh_client_ui_primitives.IconDownloadOutlineRegular;
4435
+ const IconEditOutline16 = _deepseek_ai_dsh_client_ui_primitives.IconEditOutline16 ?? _deepseek_ai_dsh_client_ui_primitives.IconEditOutlineRegular;
4436
+ const IconFullscreenOutline16 = _deepseek_ai_dsh_client_ui_primitives.IconFullscreenOutline16 ?? _deepseek_ai_dsh_client_ui_primitives.IconFullscreenOutlineRegular;
4437
+ //#endregion
4420
4438
  //#region src/image-workspace.jsx
4421
4439
  function ImageWorkspace(props) {
4422
4440
  const { preference, t, registerOpen } = props;
@@ -4430,9 +4448,9 @@ window.__ModuleLoader__.load({
4430
4448
  dispose();
4431
4449
  };
4432
4450
  }, [registerOpen]);
4433
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [settings.imageSketch && settings.imageEditing ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
4451
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [settings.imageSketch && settings.imageEditing ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tooltip, {
4434
4452
  label: t("sketch"),
4435
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
4453
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
4436
4454
  variant: "toolbar",
4437
4455
  size: "sm",
4438
4456
  "aria-label": t("sketch"),
@@ -4506,6 +4524,8 @@ window.__ModuleLoader__.load({
4506
4524
  //#endregion
4507
4525
  //#region src/client-locales.js
4508
4526
  const zh = {
4527
+ runtimeIncompatible: "检测到不兼容的 Codex 子任务组件,请卸载后重启,再安装受支持版本。",
4528
+ runtimeManagedElsewhere: "此组件由宿主或其他依赖管理,请在 DSH 插件管理中查看;这里不能直接卸载。",
4509
4529
  runtimeLoading: "正在检查组件…",
4510
4530
  runtimeRestart: "组件已更新,请重启 DSH 后使用。",
4511
4531
  runtime_installing: "正在通过 DSH 安装组件…",
@@ -4957,6 +4977,8 @@ window.__ModuleLoader__.load({
4957
4977
  imageRemoveAnnotation: "删除标注"
4958
4978
  };
4959
4979
  const en = {
4980
+ runtimeIncompatible: "An incompatible Codex subtask component was found. Uninstall it, restart DSH, then install the supported version.",
4981
+ runtimeManagedElsewhere: "This component is managed by the host or another dependency. Check DSH plugin management; it cannot be removed here.",
4960
4982
  runtimeLoading: "Checking component…",
4961
4983
  runtimeRestart: "Component changed. Restart DSH before using it.",
4962
4984
  runtime_installing: "Installing through DSH…",
@@ -6001,7 +6023,7 @@ window.__ModuleLoader__.load({
6001
6023
  invoke();
6002
6024
  },
6003
6025
  children: [
6004
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, {}),
6026
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconEditOutline16, {}),
6005
6027
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6006
6028
  className: "dcsiv-label",
6007
6029
  children: label ?? t("imageEdit")
@@ -6055,7 +6077,7 @@ window.__ModuleLoader__.load({
6055
6077
  onClick: () => {
6056
6078
  invoke();
6057
6079
  },
6058
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconDownloadOutline16, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6080
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconDownloadOutline16, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6059
6081
  className: "dcsiv-label",
6060
6082
  children: state === "pending" ? `${label} ${progress}% · ${t("cancel")}` : label
6061
6083
  })]
@@ -6244,7 +6266,7 @@ window.__ModuleLoader__.load({
6244
6266
  resetGesture();
6245
6267
  setAnnotating((value) => !value);
6246
6268
  },
6247
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6269
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconEditOutline16, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6248
6270
  className: "dcsiv-label",
6249
6271
  children: annotating ? t("imageAnnotateCancel") : t("imageAnnotate")
6250
6272
  })]
@@ -6272,7 +6294,7 @@ window.__ModuleLoader__.load({
6272
6294
  className: "dcsiv-button",
6273
6295
  "aria-label": t("imageFit"),
6274
6296
  onClick: fit,
6275
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconFullscreenOutline16, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6297
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconFullscreenOutline16, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6276
6298
  className: "dcsiv-label",
6277
6299
  children: t("imageFit")
6278
6300
  })]
@@ -6291,7 +6313,7 @@ window.__ModuleLoader__.load({
6291
6313
  className: "dcsiv-download",
6292
6314
  href: item.src,
6293
6315
  download: downloadName(item.name),
6294
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconDownloadOutline16, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6316
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconDownloadOutline16, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6295
6317
  className: "dcsiv-label",
6296
6318
  children: t("imageDownload")
6297
6319
  })]
@@ -6316,7 +6338,7 @@ window.__ModuleLoader__.load({
6316
6338
  className: "dcsiv-close-floating",
6317
6339
  "aria-label": t("imageClosePreview"),
6318
6340
  onClick: () => service.close(),
6319
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16, {})
6341
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCloseOutline16, {})
6320
6342
  }),
6321
6343
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6322
6344
  className: "dcsiv-workspace",
@@ -6406,7 +6428,7 @@ window.__ModuleLoader__.load({
6406
6428
  setAnnotations((current) => current.filter((entry) => entry.id !== annotation.id));
6407
6429
  setSelected(void 0);
6408
6430
  },
6409
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16, {})
6431
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCloseOutline16, {})
6410
6432
  })
6411
6433
  ]
6412
6434
  }) : null]
@@ -6420,7 +6442,7 @@ window.__ModuleLoader__.load({
6420
6442
  event.stopPropagation();
6421
6443
  setIndex((value) => (value - 1 + request.items.length) % request.items.length);
6422
6444
  },
6423
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronLeftOutline14, {})
6445
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronLeftOutline14, {})
6424
6446
  }),
6425
6447
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6426
6448
  type: "button",
@@ -6430,7 +6452,7 @@ window.__ModuleLoader__.load({
6430
6452
  event.stopPropagation();
6431
6453
  setIndex((value) => (value + 1) % request.items.length);
6432
6454
  },
6433
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14, {})
6455
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronRightOutline14, {})
6434
6456
  }),
6435
6457
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6436
6458
  className: "dcsiv-counter",
@@ -6454,7 +6476,7 @@ window.__ModuleLoader__.load({
6454
6476
  onClick: () => {
6455
6477
  copyNotes();
6456
6478
  },
6457
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCopyOutline16, {}), copied ? t("imageCopied") : t("imageCopyNotes")]
6479
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCopyOutline16, {}), copied ? t("imageCopied") : t("imageCopyNotes")]
6458
6480
  }) : null]
6459
6481
  })
6460
6482
  ]
@@ -6663,9 +6685,6 @@ window.__ModuleLoader__.load({
6663
6685
  limitId: limit.id
6664
6686
  }))).filter((window) => Number.isFinite(window.remainingPercent) && window.remainingPercent >= 0 && window.remainingPercent <= (mode === "custom" ? readCapabilitySettings(thresholds)[window.windowSeconds > 0 && window.windowSeconds <= 6 * 3600 ? "quotaShortThreshold" : "quotaLongThreshold"] : mode === "early" && window.windowSeconds > 0 && window.windowSeconds <= 6 * 3600 ? 50 : 20) && (!Number.isFinite(window.resetsAt) || window.resetsAt * 1e3 > now)).sort((a, b) => a.remainingPercent - b.remainingPercent)[0];
6665
6687
  }
6666
- //#endregion
6667
- //#region src/settings-contract.js
6668
- const SETTINGS_NAMESPACE = "codex-subscription";
6669
6688
  const QUICK_QUOTA_MODE_FIELD = "quickQuotaMode";
6670
6689
  const LEGACY_QUICK_QUOTA_FIELD = "quickQuotaVisible";
6671
6690
  const QUICK_QUOTA_MODE_PERCENT = "percent";
@@ -7255,7 +7274,7 @@ window.__ModuleLoader__.load({
7255
7274
  }
7256
7275
  //#endregion
7257
7276
  //#region src/version.js
7258
- const PACKAGE_VERSION = "2.1.3";
7277
+ const PACKAGE_VERSION = "2.1.5-beta.1";
7259
7278
  //#endregion
7260
7279
  //#region src/client-recovery.js
7261
7280
  async function recoveryCall(rpc, endpoint, payload = {}, timeoutMs = 1e4) {
@@ -7359,7 +7378,7 @@ window.__ModuleLoader__.load({
7359
7378
  (0, react.useEffect)(() => () => clearTimeout(dismissTimer.current), []);
7360
7379
  const id = (0, react.useId)();
7361
7380
  const visible = open && quotaEnabled && !!quotas?.length;
7362
- const position = (0, _deepseek_ai_dsh_client_ui_primitives.useAnchoredPosition)({
7381
+ const position = useAnchoredPosition({
7363
7382
  open: visible,
7364
7383
  anchorRef: trigger,
7365
7384
  panelRef: panel,
@@ -7367,7 +7386,7 @@ window.__ModuleLoader__.load({
7367
7386
  gap: 8,
7368
7387
  margin: 12
7369
7388
  });
7370
- (0, _deepseek_ai_dsh_client_ui_primitives.useDismissOnOutsidePointer)(trigger, visible, dismiss, panel);
7389
+ useDismissOnOutsidePointer(trigger, visible, dismiss, panel);
7371
7390
  (0, react.useEffect)(() => {
7372
7391
  setOpen(false);
7373
7392
  }, [current?.model, quotaEnabled]);
@@ -7640,7 +7659,7 @@ window.__ModuleLoader__.load({
7640
7659
  })]
7641
7660
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7642
7661
  className: "codexModelSelectCheck",
7643
- children: selected ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutline16, {}) : null
7662
+ children: selected ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCheckOutline16, {}) : null
7644
7663
  })]
7645
7664
  }, key);
7646
7665
  const cell = (target, label, value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
@@ -7660,7 +7679,7 @@ window.__ModuleLoader__.load({
7660
7679
  className: "codexModelSelectCellValue",
7661
7680
  children: value
7662
7681
  }),
7663
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14, { className: "codexModelSelectCellChevron" })
7682
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronRightOutline14, { className: "codexModelSelectCellChevron" })
7664
7683
  ]
7665
7684
  });
7666
7685
  let submenu = null;
@@ -7800,7 +7819,7 @@ window.__ModuleLoader__.load({
7800
7819
  className: "codexModelSelectEffort",
7801
7820
  children: effortLabel
7802
7821
  }),
7803
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { className: "codexModelSelectChevron" })
7822
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronDownOutline14, { className: "codexModelSelectChevron" })
7804
7823
  ]
7805
7824
  }), open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7806
7825
  className: "codexModelSelectMenu",
@@ -7862,7 +7881,7 @@ window.__ModuleLoader__.load({
7862
7881
  className: "codexSubscriptionPreferenceHint",
7863
7882
  children: hint
7864
7883
  }) : null]
7865
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
7884
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Menu, {
7866
7885
  open: open && !disabled,
7867
7886
  items,
7868
7887
  selectedId: value,
@@ -7884,7 +7903,7 @@ window.__ModuleLoader__.load({
7884
7903
  "aria-expanded": open && !disabled,
7885
7904
  disabled,
7886
7905
  onClick: () => setOpen((current) => !current),
7887
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: text }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, {})]
7906
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: text }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronDownOutline14, {})]
7888
7907
  })
7889
7908
  })]
7890
7909
  });
@@ -7905,7 +7924,7 @@ window.__ModuleLoader__.load({
7905
7924
  className: "codexSubscriptionPreferenceHint",
7906
7925
  children: active ? modelLabel(snapshot.imageModel) : t("imageCapability_off")
7907
7926
  }),
7908
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, {})
7927
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronDownOutline14, {})
7909
7928
  ] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7910
7929
  className: "codexSubscriptionSettingsDisclosureBody",
7911
7930
  children: [
@@ -8044,7 +8063,7 @@ window.__ModuleLoader__.load({
8044
8063
  className: "codexSubscriptionPreferenceCopy",
8045
8064
  children: [
8046
8065
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("searchDomains") }),
8047
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
8066
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Input, {
8048
8067
  "aria-label": t("searchDomains"),
8049
8068
  "aria-invalid": invalid,
8050
8069
  value: domains,
@@ -8089,7 +8108,7 @@ window.__ModuleLoader__.load({
8089
8108
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [
8090
8109
  t(field),
8091
8110
  " ",
8092
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
8111
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Input, {
8093
8112
  type: "number",
8094
8113
  min: 1,
8095
8114
  max: 100,
@@ -8179,6 +8198,9 @@ window.__ModuleLoader__.load({
8179
8198
  if (alive.current) setSending(false);
8180
8199
  }
8181
8200
  };
8201
+ (0, react.useEffect)(() => {
8202
+ if (state?.phase === "done") preference.load();
8203
+ }, [state?.phase]);
8182
8204
  const locked = sending || busy || state?.restartRequired || state?.active > 0;
8183
8205
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8184
8206
  className: "codexSubscriptionRuntime",
@@ -8187,17 +8209,18 @@ window.__ModuleLoader__.load({
8187
8209
  className: "codexSubscriptionPreference",
8188
8210
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8189
8211
  role: "status",
8190
- children: t(!state ? "runtimeLoading" : state.restartRequired ? "runtimeRestart" : busy ? `runtime_${state.phase}` : state.installed ? "subagentRuntimeInstalled" : "subagentRuntimeMissing")
8191
- }), state?.available ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8212
+ children: t(!state ? "runtimeLoading" : state.restartRequired ? "runtimeRestart" : busy ? `runtime_${state.phase}` : state.installed ? "subagentRuntimeInstalled" : state.present ? "runtimeIncompatible" : "subagentRuntimeMissing")
8213
+ }), state?.available ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
8192
8214
  type: "button",
8193
8215
  variant: "outline",
8194
- disabled: locked || state.installed && !state.removable,
8195
- onClick: () => state.installed ? setConfirm(true) : void act("install"),
8196
- children: t(state.installed ? "runtimeRemove" : "runtimeInstall")
8216
+ disabled: locked || state.present && !state.removable,
8217
+ onClick: () => state.present ? setConfirm(true) : void act("install"),
8218
+ children: t(state.present ? "runtimeRemove" : "runtimeInstall")
8197
8219
  }) : null]
8198
8220
  }),
8221
+ state?.present && state.available && !state.removable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("runtimeManagedElsewhere") }) : null,
8199
8222
  state?.active > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("runtimeActive") }) : null,
8200
- busy && state.phase === "installing" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8223
+ busy && state.phase === "installing" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
8201
8224
  type: "button",
8202
8225
  variant: "outline",
8203
8226
  disabled: sending,
@@ -8211,14 +8234,14 @@ window.__ModuleLoader__.load({
8211
8234
  "aria-label": t("runtimeRemove"),
8212
8235
  children: [
8213
8236
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("runtimeConfirm") }),
8214
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8237
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
8215
8238
  type: "button",
8216
8239
  variant: "outline",
8217
8240
  onClick: () => setConfirm(false),
8218
8241
  children: t("runtimeKeep")
8219
8242
  }),
8220
8243
  " ",
8221
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8244
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
8222
8245
  type: "button",
8223
8246
  variant: "outline",
8224
8247
  disabled: locked,
@@ -8237,7 +8260,7 @@ window.__ModuleLoader__.load({
8237
8260
  role: "status",
8238
8261
  children: t("runtimeCancelled")
8239
8262
  }) : null,
8240
- !busy ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8263
+ !busy ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
8241
8264
  type: "button",
8242
8265
  variant: "outline",
8243
8266
  disabled: sending,
@@ -8443,7 +8466,7 @@ window.__ModuleLoader__.load({
8443
8466
  className: "codexSubscriptionContextHint",
8444
8467
  children: hint
8445
8468
  })]
8446
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
8469
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Menu, {
8447
8470
  open: menuOpen,
8448
8471
  items: contextModeItems,
8449
8472
  selectedId: snapshot.contextMode,
@@ -8464,7 +8487,7 @@ window.__ModuleLoader__.load({
8464
8487
  "aria-expanded": menuOpen,
8465
8488
  disabled: !writable,
8466
8489
  onClick: () => setMenuOpen((value) => !value),
8467
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: selectedMode }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, {})]
8490
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: selectedMode }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronDownOutline14, {})]
8468
8491
  })
8469
8492
  })]
8470
8493
  }),
@@ -8478,7 +8501,7 @@ window.__ModuleLoader__.load({
8478
8501
  minimum: String(Math.min(MIN_CUSTOM_CONTEXT_WINDOW, model.maximum)),
8479
8502
  value: String(model.maximum)
8480
8503
  }) })]
8481
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
8504
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Input, {
8482
8505
  "aria-label": `${model.label} ${t("contextTokens")}`,
8483
8506
  className: "codexSubscriptionContextInput",
8484
8507
  type: "number",
@@ -8516,7 +8539,7 @@ window.__ModuleLoader__.load({
8516
8539
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8517
8540
  className: "codexSubscriptionPreferenceHint",
8518
8541
  children: t(snapshot.catalogStatus?.source === "online" ? "catalogOnline" : "catalogFallback")
8519
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8542
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
8520
8543
  type: "button",
8521
8544
  variant: "outline",
8522
8545
  disabled: snapshot.modelsLoading,
@@ -8687,7 +8710,7 @@ window.__ModuleLoader__.load({
8687
8710
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8688
8711
  className: "codexSubscriptionError",
8689
8712
  children: t("preferenceFailed")
8690
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8713
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
8691
8714
  type: "button",
8692
8715
  variant: "outline",
8693
8716
  onClick: () => {
@@ -8927,7 +8950,7 @@ window.__ModuleLoader__.load({
8927
8950
  }), accountReady ? signedIn ? t("connected") : t("disconnected") : t("accountLoading")]
8928
8951
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8929
8952
  className: "codexSubscriptionActions",
8930
- children: signedIn ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8953
+ children: signedIn ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
8931
8954
  type: "button",
8932
8955
  variant: "outline",
8933
8956
  disabled: busy || loginVisible,
@@ -8936,19 +8959,19 @@ window.__ModuleLoader__.load({
8936
8959
  setAdding(true);
8937
8960
  },
8938
8961
  children: t("addAccount")
8939
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8962
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
8940
8963
  type: "button",
8941
8964
  variant: "outline",
8942
8965
  disabled: busy || loginVisible,
8943
8966
  onClick: logout,
8944
8967
  children: t("signOutAll")
8945
- })] }) : accountReady && (flow === void 0 || ["failed", "cancelled"].includes(flow.phase)) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8968
+ })] }) : accountReady && (flow === void 0 || ["failed", "cancelled"].includes(flow.phase)) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
8946
8969
  type: "button",
8947
8970
  variant: "primary",
8948
8971
  disabled: busy,
8949
8972
  onClick: () => begin("browser"),
8950
8973
  children: t("browserLogin")
8951
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8974
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
8952
8975
  type: "button",
8953
8976
  variant: "outline",
8954
8977
  disabled: busy,
@@ -8971,21 +8994,21 @@ window.__ModuleLoader__.load({
8971
8994
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8972
8995
  className: "codexSubscriptionActions",
8973
8996
  children: [
8974
- candidate.active ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8997
+ candidate.active ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
8975
8998
  type: "button",
8976
8999
  variant: "outline",
8977
9000
  disabled: busy || loginVisible,
8978
9001
  onClick: () => selectAccount(candidate.id),
8979
9002
  children: t("switchAccount")
8980
9003
  }),
8981
- accounts.length > 1 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9004
+ accounts.length > 1 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
8982
9005
  type: "button",
8983
9006
  variant: "outline",
8984
9007
  disabled: busy || loginVisible,
8985
9008
  onClick: () => removeAccount(candidate.id),
8986
9009
  children: removeId === candidate.id ? t("removeConfirm") : t("removeAccount")
8987
9010
  }) : null,
8988
- removeId === candidate.id ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9011
+ removeId === candidate.id ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
8989
9012
  type: "button",
8990
9013
  variant: "outline",
8991
9014
  disabled: busy,
@@ -9001,21 +9024,21 @@ window.__ModuleLoader__.load({
9001
9024
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9002
9025
  className: "codexSubscriptionActions",
9003
9026
  children: [
9004
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9027
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
9005
9028
  type: "button",
9006
9029
  variant: "primary",
9007
9030
  disabled: busy,
9008
9031
  onClick: () => begin("browser"),
9009
9032
  children: t("browserLogin")
9010
9033
  }),
9011
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9034
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
9012
9035
  type: "button",
9013
9036
  variant: "outline",
9014
9037
  disabled: busy,
9015
9038
  onClick: () => begin("device_code"),
9016
9039
  children: t("deviceLogin")
9017
9040
  }),
9018
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9041
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
9019
9042
  type: "button",
9020
9043
  variant: "outline",
9021
9044
  disabled: busy,
@@ -9040,7 +9063,7 @@ window.__ModuleLoader__.load({
9040
9063
  children: t("openLogin")
9041
9064
  }),
9042
9065
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("waiting") }),
9043
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9066
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
9044
9067
  type: "button",
9045
9068
  variant: "outline",
9046
9069
  disabled: busy,
@@ -9054,7 +9077,7 @@ window.__ModuleLoader__.load({
9054
9077
  onSubmit: submit,
9055
9078
  children: [
9056
9079
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("manualCode") }),
9057
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
9080
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Input, {
9058
9081
  className: "codexSubscriptionInput",
9059
9082
  value: manualCode,
9060
9083
  onChange: (event) => setManualCode(event.currentTarget.value),
@@ -9063,12 +9086,12 @@ window.__ModuleLoader__.load({
9063
9086
  }),
9064
9087
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9065
9088
  className: "codexSubscriptionActions",
9066
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9089
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
9067
9090
  type: "submit",
9068
9091
  variant: "primary",
9069
9092
  disabled: busy || manualCode.trim() === "",
9070
9093
  children: t("submit")
9071
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9094
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
9072
9095
  type: "button",
9073
9096
  variant: "outline",
9074
9097
  disabled: busy,
@@ -9088,7 +9111,7 @@ window.__ModuleLoader__.load({
9088
9111
  rel: "noreferrer",
9089
9112
  children: t("openLogin")
9090
9113
  }),
9091
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9114
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
9092
9115
  type: "button",
9093
9116
  variant: "outline",
9094
9117
  disabled: busy,
@@ -9140,7 +9163,7 @@ window.__ModuleLoader__.load({
9140
9163
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9141
9164
  className: "codexSubscriptionActions",
9142
9165
  children: [
9143
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9166
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
9144
9167
  type: "button",
9145
9168
  variant: "outline",
9146
9169
  disabled: retrying || busy,
@@ -9150,14 +9173,14 @@ window.__ModuleLoader__.load({
9150
9173
  },
9151
9174
  children: retrying ? t("accountRetrying") : t("accountRetry")
9152
9175
  }),
9153
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9176
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
9154
9177
  type: "button",
9155
9178
  variant: "outline",
9156
9179
  disabled: busy || retrying,
9157
9180
  onClick: () => void clear(),
9158
9181
  children: busy ? t("accountRetrying") : t(confirm ? "recoveryClearConfirm" : "recoveryClear")
9159
9182
  }),
9160
- confirm ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9183
+ confirm ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
9161
9184
  type: "button",
9162
9185
  variant: "outline",
9163
9186
  disabled: busy,
@@ -9208,14 +9231,14 @@ window.__ModuleLoader__.load({
9208
9231
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9209
9232
  className: "codexSubscriptionActions",
9210
9233
  children: [
9211
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9234
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
9212
9235
  type: "button",
9213
9236
  variant: "outline",
9214
9237
  disabled: busy,
9215
9238
  onClick: load,
9216
9239
  children: busy ? t("diagnosticsLoading") : t("diagnosticsLoad")
9217
9240
  }),
9218
- report === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9241
+ report === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
9219
9242
  type: "button",
9220
9243
  variant: "outline",
9221
9244
  onClick: copy,
@@ -9372,7 +9395,7 @@ window.__ModuleLoader__.load({
9372
9395
  })]
9373
9396
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9374
9397
  className: "codexSubscriptionActions",
9375
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9398
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
9376
9399
  className: "codexSubscriptionResetUse",
9377
9400
  type: "button",
9378
9401
  variant: "outline",
@@ -9418,13 +9441,13 @@ window.__ModuleLoader__.load({
9418
9441
  }) : null,
9419
9442
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9420
9443
  className: "codexSubscriptionActions",
9421
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9444
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
9422
9445
  type: "button",
9423
9446
  variant: "outline",
9424
9447
  disabled: resetBusy,
9425
9448
  onClick: cancelReset,
9426
9449
  children: t("cancel")
9427
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9450
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
9428
9451
  className: "codexSubscriptionResetFinal",
9429
9452
  type: "button",
9430
9453
  variant: "outline",
@@ -9517,7 +9540,7 @@ window.__ModuleLoader__.load({
9517
9540
  dateTime: fetchedAt.toISOString(),
9518
9541
  children: fill(t("usageUpdated"), { value: fetchedAt.toLocaleString() })
9519
9542
  })]
9520
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9543
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
9521
9544
  className: "codexSubscriptionRefresh",
9522
9545
  type: "button",
9523
9546
  variant: "outline",
@@ -9756,7 +9779,6 @@ window.__ModuleLoader__.load({
9756
9779
  "locale",
9757
9780
  "connection",
9758
9781
  "remote",
9759
- "settingsScope",
9760
9782
  "modelDirectories",
9761
9783
  "conversation",
9762
9784
  "uiConversation",
@@ -9776,7 +9798,10 @@ window.__ModuleLoader__.load({
9776
9798
  return () => tag.remove();
9777
9799
  }, "codex-subscription: style");
9778
9800
  const rpc = createSubscriptionRpcClient(ctx.get("connection").rpc);
9779
- const preference = createPreferenceController(ctx.settingsScope.bind({ namespace: SETTINGS_NAMESPACE }), rpc);
9801
+ const preference = createPreferenceController(ctx.get("settingsScope")?.bind({ namespace: "codex-subscription" }) ?? {
9802
+ getSnapshot: () => ({ status: "unavailable" }),
9803
+ subscribe: () => () => {}
9804
+ }, rpc);
9780
9805
  ctx.effect(() => {
9781
9806
  let previous = JSON.stringify(preference.getSnapshot(), (key, value) => key.startsWith("image") || key === "" ? value : void 0);
9782
9807
  return preference.subscribe(() => {
package/lib/index.js CHANGED
@@ -22,6 +22,24 @@ import z from "@deepseek-ai/schemastery";
22
22
  import { openaiCodexProvider as createOpenAICodexProvider } from "@earendil-works/pi-ai/providers/openai-codex";
23
23
  import { createModels } from "@earendil-works/pi-ai";
24
24
  import { WebError } from "@deepseek-ai/dsh-web";
25
+ //#region src/settings-adapter.js
26
+ function createSettingsAdapter(ctx, schema, config, namespace) {
27
+ if (typeof ctx.settings.register === "function") return ctx.settings.register(namespace, schema);
28
+ if (typeof ctx.settings.configure !== "function" || typeof ctx.settings.update !== "function") throw new Error("DSH settings API is unavailable");
29
+ ctx.effect(() => ctx.settings.configure({ auto: false }));
30
+ const entry = ctx.fiber.entry;
31
+ const id = entry?.options?.id ?? entry?.id;
32
+ if (!id) throw new Error("DSH settings entry is unavailable");
33
+ const get = () => Object.fromEntries(Object.entries(config).map(([key, value]) => [key, typeof value?.get === "function" ? value.get() : value]));
34
+ return {
35
+ get,
36
+ update: (patch) => ctx.settings.update(id, patch),
37
+ watch(listener) {
38
+ return ctx.on("loader/volatile-update", () => listener(get()));
39
+ }
40
+ };
41
+ }
42
+ //#endregion
25
43
  //#region src/image-models.js
26
44
  const DEFAULT_IMAGE_MODEL = "gpt-image-2";
27
45
  const IMAGE_MODELS = Object.freeze({
@@ -1056,13 +1074,18 @@ function authenticatedSubagentChild(child, { Transport, getTokens, thread, signa
1056
1074
  //#endregion
1057
1075
  //#region src/subagent-runtime.js
1058
1076
  const SUBAGENT_RUNTIME_PACKAGE = "@deepseek-ai/dsh-subagent-codex";
1059
- const SUBAGENT_RUNTIME_VERSION = "0.1.5-rc.2";
1077
+ const SUBAGENT_RUNTIME_VERSION = "0.1.5-rc.3";
1078
+ const SUPPORTED_RUNTIME_VERSIONS = /* @__PURE__ */ new Set(["0.1.5-rc.2", SUBAGENT_RUNTIME_VERSION]);
1060
1079
  const require = createRequire(import.meta.url);
1061
1080
  const execute = promisify(execFile);
1062
1081
  function inspectSubagentRuntime(resolve = require.resolve) {
1063
1082
  try {
1064
1083
  const manifestPath = resolve(`${SUBAGENT_RUNTIME_PACKAGE}/package.json`);
1065
- if (JSON.parse(readFileSync(manifestPath, "utf8")).version !== "0.1.5-rc.2") return { installed: false };
1084
+ const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
1085
+ if (!SUPPORTED_RUNTIME_VERSIONS.has(manifest.version)) return {
1086
+ installed: false,
1087
+ present: true
1088
+ };
1066
1089
  return { installed: true };
1067
1090
  } catch {
1068
1091
  return { installed: false };
@@ -1325,10 +1348,12 @@ function createRuntimeManagement({ manager, inspect, active, selectDsh }) {
1325
1348
  } catch {
1326
1349
  available = false;
1327
1350
  }
1351
+ const runtime = inspect();
1328
1352
  return {
1329
1353
  ...state,
1330
1354
  available,
1331
- installed: inspect().installed,
1355
+ installed: runtime.installed,
1356
+ present: runtime.installed || runtime.present === true || bundle?.installed === true,
1332
1357
  removable: available && bundle?.installed === true && !bundle.readOnlyReason,
1333
1358
  active: active()
1334
1359
  };
@@ -2787,7 +2812,7 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
2787
2812
  Object.freeze(["0.82.1", "0.85.1"]);
2788
2813
  //#endregion
2789
2814
  //#region src/version.js
2790
- const PACKAGE_VERSION = "2.1.3";
2815
+ const PACKAGE_VERSION = "2.1.5-beta.1";
2791
2816
  const USER_AGENT = `dsh-codex-subscription/${PACKAGE_VERSION}`;
2792
2817
  //#endregion
2793
2818
  //#region src/model-catalog.js
@@ -5045,28 +5070,30 @@ function createSearchProviderSwitcher(loader) {
5045
5070
  }
5046
5071
  });
5047
5072
  }
5048
- function apply(ctx) {
5049
- const settings = ctx.settings.register(SETTINGS_NAMESPACE, z.object({
5050
- ...Object.fromEntries(Object.entries(PREFERENCE_FIELDS).map(([field, rule]) => [field, rule.default === void 0 ? z.union(rule.choices) : z.union(rule.choices).default(rule.default)])),
5051
- imageModel: z.union(Object.keys(IMAGE_MODELS)).default(DEFAULT_IMAGE_MODEL),
5052
- imageQuality: z.union([
5053
- "auto",
5054
- "low",
5055
- "medium",
5056
- "high",
5057
- "xhigh",
5058
- "max"
5059
- ]).default("auto"),
5060
- ...Object.fromEntries(Object.entries(IMAGE_FEATURE_DEFAULTS).map(([key, value]) => [key, z.boolean().default(value)])),
5061
- [CUSTOM_CONTEXT_OVERRIDES_FIELD]: z.dict(z.number().step(1).min(1).max(MAX_CONTEXT_BUDGET)).default({}),
5062
- [SEARCH_MODE_FIELD]: z.union(SEARCH_MODES).default("live"),
5063
- [SEARCH_DOMAINS_FIELD]: z.transform(z.array(z.string()).max(20), normalizeSearchDomains).default([]),
5064
- ...Object.fromEntries(QUOTA_THRESHOLD_FIELDS.map((key) => [key, z.number().step(1).min(1).max(100).default(20)])),
5065
- [QUOTA_ALERTS_FIELD]: z.union(QUOTA_ALERT_MODES).default("important"),
5066
- [LEGACY_QUICK_QUOTA_FIELD]: z.boolean(),
5067
- [CUSTOM_CONTEXT_WINDOW_FIELD]: z.number().step(1).min(128e3).max(1e6).default(DEFAULT_CUSTOM_CONTEXT_WINDOW),
5068
- ...Object.fromEntries(Object.entries(CUSTOM_CONTEXT_MODEL_FIELDS).map(([modelKey, field]) => [field, z.number().step(1).min(128e3).max(CUSTOM_CONTEXT_MODEL_CAPS[modelKey]).default(CUSTOM_CONTEXT_MODEL_DEFAULTS[modelKey])]))
5069
- }));
5073
+ const settingsFields = {
5074
+ ...Object.fromEntries(Object.entries(PREFERENCE_FIELDS).map(([field, rule]) => [field, rule.default === void 0 ? z.union(rule.choices) : z.union(rule.choices).default(rule.default)])),
5075
+ imageModel: z.union(Object.keys(IMAGE_MODELS)).default(DEFAULT_IMAGE_MODEL),
5076
+ imageQuality: z.union([
5077
+ "auto",
5078
+ "low",
5079
+ "medium",
5080
+ "high",
5081
+ "xhigh",
5082
+ "max"
5083
+ ]).default("auto"),
5084
+ ...Object.fromEntries(Object.entries(IMAGE_FEATURE_DEFAULTS).map(([key, value]) => [key, z.boolean().default(value)])),
5085
+ [CUSTOM_CONTEXT_OVERRIDES_FIELD]: z.dict(z.number().step(1).min(1).max(MAX_CONTEXT_BUDGET)).default({}),
5086
+ [SEARCH_MODE_FIELD]: z.union(SEARCH_MODES).default("live"),
5087
+ [SEARCH_DOMAINS_FIELD]: z.transform(z.array(z.string()).max(20), normalizeSearchDomains).default([]),
5088
+ ...Object.fromEntries(QUOTA_THRESHOLD_FIELDS.map((key) => [key, z.number().step(1).min(1).max(100).default(20)])),
5089
+ [QUOTA_ALERTS_FIELD]: z.union(QUOTA_ALERT_MODES).default("important"),
5090
+ [LEGACY_QUICK_QUOTA_FIELD]: z.boolean(),
5091
+ [CUSTOM_CONTEXT_WINDOW_FIELD]: z.number().step(1).min(128e3).max(1e6).default(DEFAULT_CUSTOM_CONTEXT_WINDOW),
5092
+ ...Object.fromEntries(Object.entries(CUSTOM_CONTEXT_MODEL_FIELDS).map(([modelKey, field]) => [field, z.number().step(1).min(128e3).max(CUSTOM_CONTEXT_MODEL_CAPS[modelKey]).default(CUSTOM_CONTEXT_MODEL_DEFAULTS[modelKey])]))
5093
+ };
5094
+ const Config = z.object(Object.fromEntries(Object.entries(settingsFields).map(([key, field]) => [key, typeof field.volatile === "function" ? field.volatile() : field])));
5095
+ function apply(ctx, config = {}) {
5096
+ const settings = createSettingsAdapter(ctx, z.object(settingsFields), config, SETTINGS_NAMESPACE);
5070
5097
  const searchProvider = createSearchProviderSwitcher(ctx.loader);
5071
5098
  const network = createCodexNetworkTransport();
5072
5099
  const originalImages = new OriginalImageStore();
@@ -5400,4 +5427,4 @@ function apply(ctx) {
5400
5427
  }, "codex-subscription: DSH-trusted account RPC"));
5401
5428
  }
5402
5429
  //#endregion
5403
- export { CODEX_IMAGE_GENERATION_URL, CODEX_IMAGE_TOOL_NAME, CODEX_RESET_CONSUME_URL, CODEX_RESET_CREDITS_URL, CODEX_USAGE_URL, CodexLoginCoordinator, DshOAuthCredentialStore, apply, assertCodexAuthUrl, commandForCodexAuthUrl, createCodexAuthService, createCodexImageTool, createCodexResetCreditService, createCodexRpcHandler, createCodexUsageReader, createSearchProviderSwitcher, createSubscriptionDiagnostics, createSubscriptionRpcHandler, decodeCodexPng, inject, name, normalizeContextMode, normalizeCustomContextWindow, openCodexAuthUrl, parseCodexUsage };
5430
+ export { CODEX_IMAGE_GENERATION_URL, CODEX_IMAGE_TOOL_NAME, CODEX_RESET_CONSUME_URL, CODEX_RESET_CREDITS_URL, CODEX_USAGE_URL, CodexLoginCoordinator, Config, DshOAuthCredentialStore, apply, assertCodexAuthUrl, commandForCodexAuthUrl, createCodexAuthService, createCodexImageTool, createCodexResetCreditService, createCodexRpcHandler, createCodexUsageReader, createSearchProviderSwitcher, createSubscriptionDiagnostics, createSubscriptionRpcHandler, decodeCodexPng, inject, name, normalizeContextMode, normalizeCustomContextWindow, openCodexAuthUrl, parseCodexUsage };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-codex-subscription",
3
- "version": "2.1.3",
3
+ "version": "2.1.5-beta.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",
@@ -19,7 +19,8 @@
19
19
  "compatibility.json",
20
20
  "LICENSE",
21
21
  "SECURITY.md",
22
- "THIRD_PARTY_NOTICES.md"
22
+ "THIRD_PARTY_NOTICES.md",
23
+ "icon-subscription.webp"
23
24
  ],
24
25
  "dsh": {
25
26
  "bundle": {
@@ -73,27 +74,27 @@
73
74
  "node": "^22.19.0 || >=24.0.0"
74
75
  },
75
76
  "peerDependencies": {
76
- "@deepseek-ai/cordis": "4.0.1 || 4.0.2",
77
- "@deepseek-ai/dsh-api-remotes": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
78
- "@deepseek-ai/dsh-client-connection": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
79
- "@deepseek-ai/dsh-client-locale": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
80
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
81
- "@deepseek-ai/dsh-client-ui-model-selection": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
82
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
83
- "@deepseek-ai/dsh-client-ui-settings": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
84
- "@deepseek-ai/dsh-client-ui-slots": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
85
- "@deepseek-ai/dsh-client-ui-tool": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
86
- "@deepseek-ai/dsh-credentials": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
87
- "@deepseek-ai/dsh-llm": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
88
- "@deepseek-ai/dsh-llm-pi-ai": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
89
- "@deepseek-ai/dsh-settings": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
90
- "@deepseek-ai/dsh-tools": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
91
- "@deepseek-ai/dsh-web": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
77
+ "@deepseek-ai/cordis": "4.0.1 || 4.0.2 || 4.0.3",
78
+ "@deepseek-ai/dsh-api-remotes": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1 || 0.1.7-alpha.2",
79
+ "@deepseek-ai/dsh-client-connection": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1 || 0.1.7-alpha.2",
80
+ "@deepseek-ai/dsh-client-locale": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1 || 0.1.7-alpha.2",
81
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1 || 0.1.7-alpha.2",
82
+ "@deepseek-ai/dsh-client-ui-model-selection": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1 || 0.1.7-alpha.2",
83
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1 || 0.1.7-alpha.2",
84
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1 || 0.1.7-alpha.2",
85
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1 || 0.1.7-alpha.2",
86
+ "@deepseek-ai/dsh-client-ui-tool": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1 || 0.1.7-alpha.2",
87
+ "@deepseek-ai/dsh-credentials": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1 || 0.1.7-alpha.2",
88
+ "@deepseek-ai/dsh-llm": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1 || 0.1.7-alpha.2",
89
+ "@deepseek-ai/dsh-llm-pi-ai": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1 || 0.1.7-alpha.2",
90
+ "@deepseek-ai/dsh-settings": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1 || 0.1.7-alpha.2",
91
+ "@deepseek-ai/dsh-tools": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1 || 0.1.7-alpha.2",
92
+ "@deepseek-ai/dsh-web": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1 || 0.1.7-alpha.2",
92
93
  "@deepseek-ai/schemastery": "3.18.1 || ^3.18.2",
93
94
  "@earendil-works/pi-ai": "0.82.1 || 0.85.1",
94
95
  "react": "^18.2.0",
95
96
  "react-dom": "^18.2.0",
96
- "@deepseek-ai/dsh-subagent-codex": "0.1.5-rc.2"
97
+ "@deepseek-ai/dsh-subagent-codex": "0.1.5-rc.2 || 0.1.5-rc.3"
97
98
  },
98
99
  "devDependencies": {
99
100
  "@deepseek-ai/cordis": "4.0.2",
@@ -134,6 +135,7 @@
134
135
  "optional": true
135
136
  }
136
137
  },
138
+ "icon": "./icon-subscription.webp",
137
139
  "scripts": {
138
140
  "build": "tsdown --config tsdown.config.mjs",
139
141
  "test:behavior": "node scripts/run-tests.mjs behavior",