dsh-codex-connect 0.1.0-alpha.4.22 → 0.1.0-alpha.4.23

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/INSTALL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Installation Runbook for CLI Agents
2
2
 
3
- Alpha 4.22 is verified with DSH `0.1.2-alpha.2` and its declared pi-ai range `^0.84.2`; the verified registry installation resolves pi-ai `0.84.4`.
3
+ Alpha 4.23 is verified with DSH `0.1.2-alpha.2` and its declared pi-ai range `^0.84.2`; the verified registry installation resolves pi-ai `0.84.4`.
4
4
 
5
5
  Install `dsh-codex-connect` into one requested DeepSeek Harness profile without changing its current default model, search route, global configuration, or OAuth state.
6
6
 
@@ -22,11 +22,11 @@ Check `dsh --version` before changing the requested profile. Use `dsh --help` to
22
22
  | --- | --- |
23
23
  | `0.1.0-rc.7` | `0.1.0-alpha.4.14` |
24
24
  | `0.1.1-rc.2` | `0.1.0-alpha.4.21` |
25
- | `0.1.2-alpha.2` | `0.1.0-alpha.4.22` |
25
+ | `0.1.2-alpha.2` | `0.1.0-alpha.4.23` |
26
26
 
27
27
  If your exact DSH version is unknown or not listed, stop and verify the combination before installing. Do not blindly install `dsh-codex-connect@alpha`: `alpha` is a moving tag, not a compatibility guarantee. Do not infer support for newer DSH versions from these rows.
28
28
 
29
- Alpha 4.22's verified contract is DSH plugin API packages `0.1.2-alpha.2`, `@earendil-works/pi-ai` `^0.84.2` (resolved as `0.84.4` during verification), and Node.js `^22.19.0 || >=24.0.0`. Alpha 4.21 remains the verified choice for DSH `0.1.1-rc.2`; staying on DSH `0.1.0-rc.7` means selecting Alpha 4.14. Upgrading DSH is a separate decision: upgrade the DSH API packages and pi-ai together, then rerun `dsh-codex-connect doctor --json` and `pnpm --silent run check:compatibility` for the selected combination.
29
+ Alpha 4.23's verified contract is DSH plugin API packages `0.1.2-alpha.2`, `@earendil-works/pi-ai` `^0.84.2` (resolved as `0.84.4` during verification), and Node.js `^22.19.0 || >=24.0.0`. Alpha 4.22 remains an earlier verified choice for the same DSH version, and Alpha 4.21 remains the verified choice for DSH `0.1.1-rc.2`; staying on DSH `0.1.0-rc.7` means selecting Alpha 4.14. Upgrading DSH is a separate decision: upgrade the DSH API packages and pi-ai together, then rerun `dsh-codex-connect doctor --json` and `pnpm --silent run check:compatibility` for the selected combination.
30
30
 
31
31
  These choices reflect the repository's existing verification record, not a new installation or runtime probe. This guidance does not fix upstream DSH compatibility or resolve [Issue #64](https://github.com/franksong2702/dsh-codex-connect/issues/64).
32
32
 
@@ -45,13 +45,13 @@ These choices reflect the repository's existing verification record, not a new i
45
45
  dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.21
46
46
  ```
47
47
 
48
- After the matching package is published, use Alpha 4.22 with DSH `0.1.2-alpha.2`:
48
+ For DSH `0.1.2-alpha.2`, use Alpha 4.23:
49
49
 
50
50
  ```sh
51
- dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.22
51
+ dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.23
52
52
  ```
53
53
 
54
- If npm is unavailable after the matching GitHub prerelease is created, use `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.21'` only for the DSH `0.1.1-rc.2` combination, or `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.22'` only for the DSH `0.1.2-alpha.2` combination.
54
+ If npm is unavailable after the matching GitHub prerelease is created, use `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.21'` only for the DSH `0.1.1-rc.2` combination, or `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.23'` only for the DSH `0.1.2-alpha.2` combination.
55
55
 
56
56
  3. Run `dsh --profile web --dump-config` and require exactly one `llm-openai-codex` row loading `dsh-codex-connect`.
57
57
  4. Confirm the effective `agent-default-model` and `web.searchProvider` values are unchanged from before installation.
@@ -63,7 +63,7 @@ These choices reflect the repository's existing verification record, not a new i
63
63
 
64
64
  6. If the user explicitly requests login, open **Settings → Plugins → Plugin configuration → Codex Connect**, or check `status` and then use `login` or `login --device-code`. OAuth approval belongs to the user.
65
65
 
66
- Alpha 4.22 additionally offers the same account actions in **Settings → Models → Openai-Codex**, plus a shared **More settings** dialog for model visibility, proxy, search, image, and context-budget controls. The original Plugin settings entry remains available; neither entry automatically starts login or changes model/search defaults.
66
+ Alpha 4.23 offers the same account actions in **Settings → Models → Openai-Codex**, plus a shared **More settings** dialog for model visibility, proxy, search, image, and context-budget controls. The original Plugin settings entry remains available; neither entry automatically starts login or changes model/search defaults.
67
67
 
68
68
  When signed out, select **Authorize**. When signed in, use **Sign out** or **View quota**; use **More settings** for plugin options. If authorization is abandoned, use **Reopen authorization** or **Cancel sign-in** and retry; cancellation does not delete an existing account. Pending authorization expires after 10 minutes by default (`oauthTimeoutMs` in plugin configuration, applied on load).
69
69
 
package/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # git hash-object README.md docs/README.zh.md
5
- README.md: a70138a6cef1b38bf564eb3d187046a2388305a1
6
- docs/README.zh.md: f44a46b738a80bbb13765bb27f9424890c6d8663
5
+ README.md: 5166f2ac28ab4497ab1d52151fa773ce845ed25c
6
+ docs/README.zh.md: ed0a2c4fc2ecb25fcd85a917014278354837d894
package/README.md CHANGED
@@ -18,24 +18,23 @@ The setup and image-result screenshots in this English guide are captured from t
18
18
 
19
19
  ## Quick start (about five minutes)
20
20
 
21
- This guide uses the `web` profile. Replace `web` with the name of the Harness profile you already use. You need a working `dsh` installation; from a DeepSeek Harness source checkout, prefix the commands with `pnpm`.
21
+ This quick start targets DSH `0.1.2-alpha.2` with Codex Connect Alpha 4.23. Check `dsh --version` first. For DSH `0.1.1-rc.2` or `0.1.0-rc.7`, select the matching plugin version in [INSTALL.md](INSTALL.md). This guide uses the `web` profile; replace `web` with the name of the Harness profile you already use. From a DeepSeek Harness source checkout, prefix the commands with `pnpm`.
22
22
 
23
23
  ### 1. Install the plugin into one profile
24
24
 
25
25
  ```sh
26
- dsh plugin --profile web add dsh-codex-connect@alpha
26
+ dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.23
27
27
  ```
28
28
 
29
29
  Expected result: the package is added to that profile. This does not change the profile's default model or global search route.
30
30
 
31
- After its matching package is published, install Alpha 4.22 exactly with `dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.22`.
31
+ Use the exact version above to keep the verified DSH and plugin pair reproducible. `alpha` is a moving npm tag, not a compatibility guarantee.
32
32
 
33
- ### What's new in Alpha 4.22
33
+ ### What's new in Alpha 4.23
34
34
 
35
- - Target the DSH `0.1.2-alpha.2` client settings and session-controller APIs together with its declared `@earendil-works/pi-ai` range `^0.84.2`.
36
- - Manage ChatGPT authorization, quota and shared Codex Connect settings from a compact **Openai-Codex** card in **Settings → Models**, while retaining the original Plugin settings entry.
37
- - Continue, cancel or retry an interrupted browser authorization without restarting DSH or deleting an existing credential. The full authorization flow has a configurable bounded deadline.
38
- - Adjust a bounded local context budget per visible Codex model with a linked slider and numeric input. Catalog defaults remain in effect until an override is saved; the configuration limit is not a claim about the service-side context capacity.
35
+ - Open and render Web sessions normally on DSH `0.1.2-alpha.2`; the Composer model directory now declares the nested session remote it uses.
36
+ - Probe the hidden `codex-auto-review` approval reviewer with one explicit, synthetic no-op through `auto-review-probe`. The command does not add a selectable model, review a real command, refresh credentials, or enable Auto-review.
37
+ - Keep the quick-start command pinned to the verified DSH `0.1.2-alpha.2` pair and avoid duplicate upstream Canary runs when npm channels resolve to the same DSH version.
39
38
 
40
39
  ### Version updates
41
40
 
@@ -43,9 +42,7 @@ Codex Connect checks public package metadata and this repository's `verified-com
43
42
 
44
43
  The compatibility record lists exact plugin and DSH versions rather than assuming every later release remains compatible. Maintainers can add a newly verified DSH version to the repository file without publishing another plugin release. A green result means the installed pair was verified; yellow means the latest plugin was verified with the installed DSH version and should be installed first; red means the installed DSH version is known but neither the installed plugin nor the latest published plugin has a matching record; gray means the installed DSH version is not recorded or the public record could not be checked. A red result includes a prefilled GitHub issue link for the installed DSH version so users can remind the maintainer without composing a report from scratch.
45
44
 
46
- When a newer plugin version is available, a frame-wide DSH notice appears even if you switch conversations. It first shows the user-facing changes between your installed version and the newest version; technical release notes are available as a secondary detail, or from the release page. The plugin never runs an upgrade command by itself.
47
-
48
- The notice first summarizes the user-facing changes between your installed version and the newest version. Technical release notes remain available as a secondary detail. To update, copy the short request shown in the notice to the Agent you use for this DSH project. The Agent can inspect the project instructions and choose the appropriate install or update method; the plugin does not execute anything on your behalf.
45
+ When a newer plugin version is available, a frame-wide DSH notice appears even if you switch conversations. It first shows the user-facing changes between your installed version and the newest version; technical release notes remain available as a secondary detail or from the release page. To update, copy the short request shown in the notice to the Agent you use for this DSH project. The Agent can inspect the project instructions and choose the appropriate install or update method; the plugin never runs an upgrade command itself.
49
46
 
50
47
  After the Agent reports completion, return to the notice or settings card and select **Done — check again**. If the running process still reports the old version, restart that profile's DSH Web process and check again.
51
48
 
@@ -65,15 +62,17 @@ dsh web
65
62
 
66
63
  Expected result: the Harness web UI opens for the selected profile.
67
64
 
68
- ### 3. Find the Codex Connect card
65
+ ### 3. Find the Openai-Codex account card
69
66
 
70
- Open **Settings → Plugins → Plugin configuration → Codex Connect**.
67
+ Open **Settings → Models** and find **Openai-Codex**. This is the primary Alpha 4.23 account entry. If the profile does not expose the Models settings section, open **Settings → Plugins → Plugin configuration → Codex Connect** instead.
71
68
 
72
- Alpha 4.22 for DSH `0.1.2-alpha.2` also includes an **Openai-Codex** account card in **Settings → Models**, with the attribution “Powered by the Codex Connect plugin.” for ChatGPT sign-in, reauthorization, sign-out and quota. Both pages share one in-memory account state and polling owner. **More settings** opens the existing proxy, model visibility, search, image and context-budget configuration form in a dialog; the original Plugin settings entry remains available. Both entries save to the same settings scope. Close or Escape discards unsaved dialog edits. The Models footer is optional: profiles without that settings section retain the existing Plugin entry.
69
+ The Models card carries the attribution “Powered by the Codex Connect plugin.” and provides ChatGPT authorization, reauthorization, sign-out and quota. Both settings pages share one in-memory account state and polling owner. **More settings** opens the proxy, model visibility, search, image and context-budget configuration form in a dialog; the original Plugin settings entry remains available. Both entries save to the same settings scope. Close or Escape discards unsaved dialog edits. The Models footer is optional: profiles without that settings section retain the existing Plugin entry.
73
70
 
74
71
  The compact Models row shows **Authorize** when signed out, or **Sign out** and **View quota** when signed in. Expanding quota shows only the server-reported usage rows, without repeating account controls. If browser authorization is interrupted, use **Continue authorization** in Models (**Reopen authorization** in Plugins) to resume the pending login, or **Cancel sign-in** and retry from either settings page or another trusted browser. Cancellation preserves an existing signed-in account. An abandoned authorization expires after 10 minutes by default; the plugin's `oauthTimeoutMs` configuration accepts 1,000–1,800,000 milliseconds and applies when the plugin loads. The separate 30-second wait for the initial authorization URL remains bounded. Neither cancellation nor expiry restarts DSH.
75
72
 
76
- Expected result: a fresh installation shows **Not signed in** and a **Sign in with ChatGPT** button. The card is where you later manage optional capabilities too.
73
+ Expected result: a fresh installation shows **Authorize** in Models. The Plugin configuration fallback shows **Not signed in** and **Sign in with ChatGPT**.
74
+
75
+ The screenshot below shows the retained Plugin configuration fallback.
77
76
 
78
77
  <p align="center">
79
78
  <img src="https://raw.githubusercontent.com/franksong2702/dsh-codex-connect/main/docs/assets/en/plugin-entry.jpg" alt="Collapsed English-localized Codex Connect entry under Harness plugin configuration" width="586">
@@ -81,9 +80,9 @@ Expected result: a fresh installation shows **Not signed in** and a **Sign in wi
81
80
 
82
81
  ### 4. Sign in with ChatGPT
83
82
 
84
- Click **Sign in with ChatGPT** and complete the browser approval yourself. If an embedded WebView blocks the sign-in window, use the displayed **Open ChatGPT sign-in page** link to continue in your system browser. Do not copy an authorization URL, code, token, or account identifier into an issue, log, or configuration file.
83
+ Select **Authorize** in Models, or **Sign in with ChatGPT** in Plugin configuration, and complete the browser approval yourself. If an embedded WebView blocks the sign-in window, use the displayed **Open ChatGPT sign-in page** link to continue in your system browser. Do not copy an authorization URL, code, token, or account identifier into an issue, log, or configuration file.
85
84
 
86
- Expected result: the account area changes to **Signed in**. The screenshot below is the successful end state after this step; it is not the initial sign-in screen.
85
+ Expected result: Models shows **Sign out** and **View quota**. The Plugin configuration account area shows **Signed in**. The screenshot below shows that fallback view after a successful sign-in; it is not the initial sign-in screen.
87
86
 
88
87
  <p align="center">
89
88
  <img src="https://raw.githubusercontent.com/franksong2702/dsh-codex-connect/main/docs/assets/en/oauth-status.jpg" alt="English-localized Codex Connect signed-in state inside Harness plugin configuration" width="720">
@@ -305,9 +304,21 @@ The report labels each check `supported`, `rejected`, or `unknown`, with a reaso
305
304
 
306
305
  This report covers only the standalone route, not active profile routing, search/image tools, browser compatibility, provider retry behavior, or session recovery. Automatic provider failover is `rejected` because this plugin does not implement it; select an alternative provider explicitly. WebSocket-to-SSE fallback is inactive with the finite SSE default. `contextManagement` and continuation remain `unknown`; native compaction and WebSocket reuse are `rejected` by the current integration policy. No diagnostic result enables these capabilities or changes Harness history. Exit codes cover runtime, OAuth, selected model, Responses, and SSE only: `0` means all five were supported, `1` means at least one was rejected, and `2` means unknown evidence, invalid options, or an inspection failure. Rejected optional capabilities do not change that exit code.
307
306
 
307
+ ### Hidden approval-review capability probe
308
+
309
+ Issue #84 is being investigated with a separate, opt-in probe. It does not add `codex-auto-review` to the model selector and does not review or execute a real Harness command.
310
+
311
+ ```sh
312
+ dsh plugin --profile web exec dsh-codex-connect auto-review-probe --json
313
+ ```
314
+
315
+ The command sends one fixed, synthetic no-op to the hidden reviewer through the ChatGPT OAuth Responses route. It requires an unexpired stored credential, never refreshes or writes credentials, does not follow redirects or retry, caps the response at 64 KiB, and destroys its owned connection before returning. `--proxy <http(s)-origin>` and `--timeout-ms <1..60000>` have the same explicit-network meaning as the ordinary capability probe.
316
+
317
+ `supported` means only that the route accepted the exact hidden model id and returned one complete assessment matching the reviewer JSON fields. `rejected` means the request or local prerequisite was explicitly rejected. Timeouts, cancellation, malformed output, incomplete streams, rate limits, and network failures remain `unknown`. Output omits credentials, account ids, response ids, provider messages, model text, paths, headers, and proxy origins. Exit `0` requires runtime, OAuth, and reviewer checks to be supported; exit `1` means at least one was rejected; exit `2` means evidence is unknown or input is invalid. The report is evidence only: it never enables automatic approval, changes DSH policy, or authorizes an action.
318
+
308
319
  ## Compatibility and security boundary
309
320
 
310
- - Alpha 4.22 is verified with DSH plugin API packages `0.1.2-alpha.2`, `@earendil-works/pi-ai` `^0.84.2` (resolved as `0.84.4` during verification), and Node.js `^22.19.0 || >=24.0.0`. Published Alpha 4.21 remains verified with DSH `0.1.1-rc.2` and pi-ai `0.82.1`. [verified-compatibility.json](verified-compatibility.json) records the exact pairs; see [INSTALL.md](INSTALL.md) for installation commands.
321
+ - Alpha 4.23 is verified with DSH plugin API packages `0.1.2-alpha.2`, `@earendil-works/pi-ai` `^0.84.2` (resolved as `0.84.4` during verification), and Node.js `^22.19.0 || >=24.0.0`. Published Alpha 4.22 remains an earlier verified choice for the same DSH version; Alpha 4.21 remains verified with DSH `0.1.1-rc.2` and pi-ai `0.82.1`. [verified-compatibility.json](verified-compatibility.json) records the exact pairs; see [INSTALL.md](INSTALL.md) for installation commands.
311
322
  - The new DSH client splits its former runtime into Session Controller, Settings, Store, and Renderer packages. Codex Connect uses those public interfaces for settings and image actions. DSH owns normalized preview encoding and dimensions; Codex Connect retains the exact original image separately.
312
323
  - Upgrade the DSH plugin API packages and `@earendil-works/pi-ai` as one group, then run `dsh-codex-connect doctor --json` and the compatibility check again. This contract does not make claims about future versions.
313
324
  - When the daily upstream check finds a new `latest` or `next` DSH candidate, it installs Codex Connect into an isolated profile, boots the installed model runtime without OAuth credentials, verifies model and reasoning-effort discovery, and confirms provider disposal. Live sign-in, quota, and model requests still require manual validation in the test profile.
package/docs/README.zh.md CHANGED
@@ -18,24 +18,23 @@
18
18
 
19
19
  ## 五分钟快速开始
20
20
 
21
- 本指南使用 `web` profile。请把 `web` 替换成你已经在用的 Harness profile 名称。你需要先有可用的 `dsh` 安装;如果在 DeepSeek Harness 源码 checkout 中运行,请在命令前加 `pnpm`。
21
+ 本快速指南适用于 DSH `0.1.2-alpha.2` 与 Codex Connect Alpha 4.23。请先运行 `dsh --version`。如果使用 DSH `0.1.1-rc.2` 或 `0.1.0-rc.7`,请在 [INSTALL.md](../INSTALL.md) 中选择匹配的插件版本。本指南使用 `web` profile;请把 `web` 替换成你已经在用的 Harness profile 名称。如果在 DeepSeek Harness 源码 checkout 中运行,请在命令前加 `pnpm`。
22
22
 
23
23
  ### 1. 将插件装入一个 profile
24
24
 
25
25
  ```sh
26
- dsh plugin --profile web add dsh-codex-connect@alpha
26
+ dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.23
27
27
  ```
28
28
 
29
29
  预期结果:包被加入该 profile。这个动作不会更改 profile 的默认模型或全局搜索路由。
30
30
 
31
- 匹配的 npm 包发布后,使用 `dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.22` 可以精确安装 Alpha 4.22。
31
+ 请使用上面的精确版本,确保已验证的 DSH 与插件组合可以复现。`alpha` 是会移动的 npm 标签,不是兼容性保证。
32
32
 
33
- ### Alpha 4.22 更新内容
33
+ ### Alpha 4.23 更新内容
34
34
 
35
- - 同时适配 DSH `0.1.2-alpha.2` 的客户端设置、会话控制器接口及其声明的 `@earendil-works/pi-ai` 版本范围 `^0.84.2`。
36
- - 在 **设置 → 模型** 中提供紧凑的 **Openai-Codex** 卡片,用于 ChatGPT 授权、额度和共享 Codex Connect 设置,同时保留原插件设置入口。
37
- - 浏览器授权中断后,可以继续、取消或重试,不需要重启 DSH,也不会删除已有凭据;完整授权流程使用可配置且有范围限制的期限。
38
- - 使用联动的滑条和数字输入框,逐模型调整有范围限制的本地上下文预算。保存覆盖值前继续使用目录默认值;配置上限不代表服务端上下文容量。
35
+ - 在 DSH `0.1.2-alpha.2` 中正常打开和渲染 Web 会话;Composer 模型目录现在会声明其使用的嵌套会话 remote。
36
+ - 通过 `auto-review-probe` 显式发送一条合成空操作,探测隐藏的 `codex-auto-review` 审批 reviewer。该命令不会添加可选模型、审查真实命令、刷新凭据或启用 Auto-review。
37
+ - 快速开始继续固定使用已验证的 DSH `0.1.2-alpha.2` 组合;当 npm 多个渠道解析到同一 DSH 版本时,上游 Canary 不再重复执行。
39
38
 
40
39
  ### 版本更新提醒
41
40
 
@@ -65,15 +64,17 @@ dsh web
65
64
 
66
65
  预期结果:所选 profile 的 Harness Web UI 打开。
67
66
 
68
- ### 3. 找到 Codex Connect 卡片
67
+ ### 3. 找到 Openai-Codex 账户卡
69
68
 
70
- 打开 **设置 → 插件 → 插件配置 → Codex Connect**。
69
+ 打开 **设置 → 模型**,找到 **Openai-Codex**。这是 Alpha 4.23 的主要账户入口。如果当前 profile 没有模型设置分区,请改用 **设置 → 插件 → 插件配置 → Codex Connect**。
71
70
 
72
- 面向 DSH `0.1.2-alpha.2` 的 Alpha 4.22 还在 **设置 → 模型** 中提供 **Openai-Codex** 账户卡,辅助文案标注“由 Codex Connect 插件提供支持。”,用于 ChatGPT 登录、重新授权、退出和查看额度。两个页面共用同一份内存账户状态及轮询。**更多设置** 会在弹窗中打开现有的代理、模型显示、搜索、图片和上下文预算配置表单,原插件设置入口仍保留。两处保存到同一份配置;关闭弹窗或按 Escape 会放弃弹窗内未保存的修改。模型页底部入口是可选增强:没有该设置分区的 profile 仍保留原插件入口。
71
+ 模型页账户卡标注“由 Codex Connect 插件提供支持。”,用于 ChatGPT 授权、重新授权、退出和查看额度。两个设置页面共用同一份内存账户状态及轮询。**更多设置** 会在弹窗中打开代理、模型显示、搜索、图片和上下文预算配置表单,原插件设置入口仍保留。两处保存到同一份配置;关闭弹窗或按 Escape 会放弃弹窗内未保存的修改。模型页底部入口是可选增强:没有该设置分区的 profile 仍保留原插件入口。
73
72
 
74
73
  模型页紧凑卡片在未登录时显示 **授权**,已登录时显示 **退出登录** 和 **查看额度**。展开后只显示服务端返回的额度条目,不再重复账户操作。浏览器授权中断后,可以点击模型页的 **继续授权**(插件页为 **重新打开授权**)继续原登录,或点击 **取消登录** 后,从任一设置页或另一个受信任浏览器重试。取消不会退出已有账户。未完成的授权默认在 10 分钟后到期;插件配置 `oauthTimeoutMs` 可设为 1,000–1,800,000 毫秒,在插件加载时生效。获取初始授权链接仍有独立的 30 秒等待上限。取消和到期都不需要重启 DSH。
75
74
 
76
- 预期结果:新安装时账户区显示 **尚未登录**,并出现 **使用 ChatGPT 登录** 按钮。之后管理可选能力也在同一张卡片中完成。
75
+ 预期结果:新安装时模型页显示 **授权**。插件配置备用入口显示 **尚未登录** 和 **使用 ChatGPT 登录**。
76
+
77
+ 下图展示的是保留的插件配置备用入口。
77
78
 
78
79
  <p align="center">
79
80
  <img src="https://raw.githubusercontent.com/franksong2702/dsh-codex-connect/main/docs/assets/zh/plugin-entry.jpg" alt="Harness 插件配置中的中文 Codex Connect 折叠入口" width="586">
@@ -81,9 +82,9 @@ dsh web
81
82
 
82
83
  ### 4. 使用 ChatGPT 登录
83
84
 
84
- 点击 **使用 ChatGPT 登录**,并自行完成浏览器审批。如果内嵌 WebView 阻止登录窗口,请点击页面显示的 **打开 ChatGPT 登录页面**,在系统浏览器中继续。不要把授权 URL、授权码、token 或账户标识复制到 Issue、日志或配置文件中。
85
+ 在模型页点击 **授权**,或在插件配置中点击 **使用 ChatGPT 登录**,然后自行完成浏览器审批。如果内嵌 WebView 阻止登录窗口,请点击页面显示的 **打开 ChatGPT 登录页面**,在系统浏览器中继续。不要把授权 URL、授权码、token 或账户标识复制到 Issue、日志或配置文件中。
85
86
 
86
- 预期结果:账户区变为 **已登录**。下图展示的是完成本步骤后的成功状态,不是开始登录前的页面。
87
+ 预期结果:模型页显示 **退出登录** 和 **查看额度**;插件配置的账户区显示 **已登录**。下图展示的是成功登录后的备用入口,不是开始登录前的页面。
87
88
 
88
89
  <p align="center">
89
90
  <img src="https://raw.githubusercontent.com/franksong2702/dsh-codex-connect/main/docs/assets/zh/oauth-status.jpg" alt="Harness 插件配置中的中文 Codex Connect 已登录状态" width="720">
@@ -305,9 +306,21 @@ dsh plugin --profile web exec dsh-codex-connect capabilities --model gpt-5.6-sol
305
306
 
306
307
  本报告仅涵盖独立路由,不验证活动 profile 路由、搜索/图片工具、浏览器兼容性、provider 重试行为或会话恢复。本插件没有实现自动 provider 故障切换,因此该项为 `rejected`,需要用户明确选择其他 provider。有限 SSE 默认路径不会触发 WebSocket 到 SSE 的回退。`contextManagement` 和续接仍为 `unknown`;原生 compaction 和 WebSocket reuse 在当前集成策略下为 `rejected`。诊断结果不会启用这些能力,也不会更改 Harness 历史。退出码只覆盖运行时、OAuth、所选模型、Responses 和 SSE:`0` 表示五项均可用,`1` 表示至少一项被拒绝,`2` 表示证据未知、选项无效或检查失败。被拒绝的可选能力不影响该退出码。
307
308
 
309
+ ### 隐藏审批审查能力探针
310
+
311
+ Issue #84 使用一条独立、按需执行的探针开展调研。它不会把 `codex-auto-review` 加入模型选择器,也不会审查或执行真实的 Harness 命令。
312
+
313
+ ```sh
314
+ dsh plugin --profile web exec dsh-codex-connect auto-review-probe --json
315
+ ```
316
+
317
+ 该命令通过 ChatGPT OAuth Responses 路由向隐藏 reviewer 发送一条固定的合成空操作。它要求已存凭据尚未过期,不刷新或写入凭据,不跟随重定向、不重试,响应上限为 64 KiB,并在返回前销毁自有连接。`--proxy <http(s)-origin>` 和 `--timeout-ms <1..60000>` 与普通能力探针具有相同的显式网络含义。
318
+
319
+ `supported` 只表示路由接受了精确的隐藏模型 ID,并返回一条符合 reviewer JSON 字段的完整审查结果。`rejected` 表示请求或本地前置条件被明确拒绝。超时、取消、格式错误、不完整流、限流和网络故障均保持 `unknown`。输出会省略凭据、账号 ID、response ID、服务端消息、模型文本、路径、headers 和代理 origin。只有运行时、OAuth 和 reviewer 三项均为可用时才返回 `0`;至少一项被拒绝时返回 `1`;证据未知或输入无效时返回 `2`。该报告只提供证据:它绝不会启用自动审批、修改 DSH 策略或授权任何操作。
320
+
308
321
  ## 兼容性与安全边界
309
322
 
310
- - Alpha 4.22 已与 DSH 插件 API packages `0.1.2-alpha.2`、`@earendil-works/pi-ai` `^0.84.2`(验证时解析为 `0.84.4`)和 Node.js `^22.19.0 || >=24.0.0` 完成验证。已发布 Alpha 4.21 仍与 DSH `0.1.1-rc.2` 和 pi-ai `0.82.1` 保持已验证状态。[verified-compatibility.json](../verified-compatibility.json) 记录精确组合;安装命令见 [INSTALL.md](../INSTALL.md)。
323
+ - Alpha 4.23 已与 DSH 插件 API packages `0.1.2-alpha.2`、`@earendil-works/pi-ai` `^0.84.2`(验证时解析为 `0.84.4`)和 Node.js `^22.19.0 || >=24.0.0` 完成验证。已发布 Alpha 4.22 仍是同一 DSH 版本较早的已验证选择;Alpha 4.21 仍与 DSH `0.1.1-rc.2` 和 pi-ai `0.82.1` 保持已验证状态。[verified-compatibility.json](../verified-compatibility.json) 记录精确组合;安装命令见 [INSTALL.md](../INSTALL.md)。
311
324
  - 新版 DSH 将原来的 client runtime 拆分为 Session Controller、Settings、Store 和 Renderer 包。Codex Connect 通过这些公开接口接入设置和图片操作。规范化预览的编码与尺寸由 DSH 决定;Codex Connect 另行保留字节完全一致的原图。
312
325
  - 升级时请将 DSH 插件 API packages 与 `@earendil-works/pi-ai` 作为一组升级,再运行 `dsh-codex-connect doctor --json` 和兼容性检查。本契约不对未来版本作判断。
313
326
  - 每日上游检查发现新的 DSH `latest` 或 `next` 候选版本时,会把 Codex Connect 安装到隔离 Profile 中,在没有 OAuth 凭据的情况下启动已安装的模型运行时,验证模型与推理强度发现,并确认提供方可被正确卸载。真实登录、额度和模型请求仍需在测试 Profile 中人工验证。
@@ -1,4 +1,4 @@
1
1
  # Bilingual-pair consistency record for the design document. Re-record with:
2
2
  # git hash-object docs/design.md docs/design.zh.md
3
- design.md: 981c5097e5aa008ce087b3cbd9651e60e0b0dffc
4
- design.zh.md: 81327b8268011fe2bb80b203c2e430610911d0f7
3
+ design.md: 4059dfc558bfa89509534585e89ce58185081119
4
+ design.zh.md: 8d0dc555e9a3419b3ad880e45a1e1dfd8760af48
package/docs/design.md CHANGED
@@ -26,4 +26,4 @@ Before registration the plugin checks current provider ids. An existing `openai-
26
26
 
27
27
  ## Compatibility boundary
28
28
 
29
- Alpha 4.22 pins Harness `0.1.2-alpha.2` development dependencies and follows its pi-ai range `^0.84.2`; the verified release lockfile selects pi-ai `0.84.4`. Supported Node.js remains `^22.19.0 || >=24.0.0`. The keyed `settings.plugin.item` integration remains, while client types come from their Session Controller, Settings, Store, and Renderer owners instead of the removed client-runtime package. The published compatibility record lists the exact Alpha 4.22 and DSH `0.1.2-alpha.2` pair. Backend eligibility, quotas, models, service-side context capacity, and protocol details remain controlled upstream. Tests use temporary OAuth documents and mocked network responses; CI does not perform real authentication.
29
+ Alpha 4.23 pins Harness `0.1.2-alpha.2` development dependencies and follows its pi-ai range `^0.84.2`; the verified release lockfile selects pi-ai `0.84.4`. Supported Node.js remains `^22.19.0 || >=24.0.0`. The keyed `settings.plugin.item` integration remains, while client types come from their Session Controller, Settings, Store, and Renderer owners instead of the removed client-runtime package. The published compatibility record lists the exact Alpha 4.23 and DSH `0.1.2-alpha.2` pair. Backend eligibility, quotas, models, service-side context capacity, and protocol details remain controlled upstream. Tests use temporary OAuth documents and mocked network responses; CI does not perform real authentication.
package/docs/design.zh.md CHANGED
@@ -22,4 +22,4 @@ Host 将 `llm-openai-codex` 注册为插件自有的能力 settings namespace。
22
22
 
23
23
  注册前检查现有 provider id;发现 `openai-codex` 已被占用时,给出旧 bundle 或手动 provider 配置的定向迁移提示。boot-free CLI doctor 只报告包/运行时版本、OAuth 路径元数据、能力默认值和安全提示。
24
24
 
25
- Alpha 4.22 固定使用 Harness `0.1.2-alpha.2` 开发依赖,并跟随其 pi-ai 版本范围 `^0.84.2`;已验证的发布锁文件选择 pi-ai `0.84.4`。Node.js 支持范围仍为 `^22.19.0 || >=24.0.0`。keyed `settings.plugin.item` 集成保持不变,客户端类型改从 Session Controller、Settings、Store 和 Renderer 的所属包导入,不再依赖已移除的 client-runtime 包。已发布兼容性记录列出 Alpha 4.22 与 DSH `0.1.2-alpha.2` 的精确组合。资格、额度、模型、服务端上下文容量和后端协议仍由上游控制。测试仅使用临时 OAuth 文档和模拟网络响应,CI 不执行真实认证。
25
+ Alpha 4.23 固定使用 Harness `0.1.2-alpha.2` 开发依赖,并跟随其 pi-ai 版本范围 `^0.84.2`;已验证的发布锁文件选择 pi-ai `0.84.4`。Node.js 支持范围仍为 `^22.19.0 || >=24.0.0`。keyed `settings.plugin.item` 集成保持不变,客户端类型改从 Session Controller、Settings、Store 和 Renderer 的所属包导入,不再依赖已移除的 client-runtime 包。已发布兼容性记录列出 Alpha 4.23 与 DSH `0.1.2-alpha.2` 的精确组合。资格、额度、模型、服务端上下文容量和后端协议仍由上游控制。测试仅使用临时 OAuth 文档和模拟网络响应,CI 不执行真实认证。
package/lib/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { At as openAICodexModelCatalog, B as DSH_PLUGIN_API_PACKAGES, Ct as normalizeTrustedOrigin, Dt as loginOpenAICodex, J as readInstalledPackageVersion, Mt as OPENAI_CODEX_PROVIDER, Nt as OpenAICodexCredentialStore, Ot as logoutOpenAICodex, Pt as openAICodexAuthPath, St as OpenAICodexTrustedOriginsStore, c as migrateOpenAICodexSearchHistory, j as CODEX_CONNECT_VERSION, k as diagnoseOpenAICodex, kt as openAICodexAuthStatus, l as OPENAI_CODEX_BASE_URL, mt as normalizeOpenAICodexProxyUrl, q as evaluateCompatibility } from "./src-kwF-uZCG.js";
2
+ import { At as openAICodexModelCatalog, B as DSH_PLUGIN_API_PACKAGES, Ct as normalizeTrustedOrigin, Dt as loginOpenAICodex, J as readInstalledPackageVersion, Mt as OPENAI_CODEX_PROVIDER, Nt as OpenAICodexCredentialStore, Ot as logoutOpenAICodex, Pt as openAICodexAuthPath, St as OpenAICodexTrustedOriginsStore, c as migrateOpenAICodexSearchHistory, j as CODEX_CONNECT_VERSION, k as diagnoseOpenAICodex, kt as openAICodexAuthStatus, l as OPENAI_CODEX_BASE_URL, mt as normalizeOpenAICodexProxyUrl, q as evaluateCompatibility } from "./src-ByKP_wn9.js";
3
3
  import { createHash } from "node:crypto";
4
4
  import { Agent, ProxyAgent, fetch } from "undici";
5
5
  import { fileURLToPath } from "node:url";
@@ -9,17 +9,17 @@ import { createInterface } from "node:readline/promises";
9
9
  //#region src/capability-probe.ts
10
10
  /** Bounded, standalone Responses probe; never used by conversation routing. */
11
11
  /** A security limit, not a model output-token setting. */
12
- const MAX_PROBE_RESPONSE_BYTES = 65536;
13
- function record(value) {
12
+ const MAX_PROBE_RESPONSE_BYTES$1 = 65536;
13
+ function record$1(value) {
14
14
  return typeof value === "object" && value !== null && !Array.isArray(value);
15
15
  }
16
- function completedResponse(value, model) {
17
- if (!record(value) || value["status"] !== "completed" || !Array.isArray(value["output"])) return false;
16
+ function completedResponse$1(value, model) {
17
+ if (!record$1(value) || value["status"] !== "completed" || !Array.isArray(value["output"])) return false;
18
18
  if (value["model"] !== model) return false;
19
- return value["output"].some((item) => record(item) && item["type"] === "message" && item["role"] === "assistant" && Array.isArray(item["content"]) && item["content"].some((part) => record(part) && part["type"] === "output_text" && typeof part["text"] === "string" && part["text"].trim().length > 0));
19
+ return value["output"].some((item) => record$1(item) && item["type"] === "message" && item["role"] === "assistant" && Array.isArray(item["content"]) && item["content"].some((part) => record$1(part) && part["type"] === "output_text" && typeof part["text"] === "string" && part["text"].trim().length > 0));
20
20
  }
21
21
  /** Inspect complete SSE frames, not substrings inside error text or schema errors. */
22
- function completedStream(text, model) {
22
+ function completedStream$1(text, model) {
23
23
  let completed = false;
24
24
  let data = [];
25
25
  for (const line of text.split(/\r\n|\r|\n/u)) if (line === "") {
@@ -33,10 +33,10 @@ function completedStream(text, model) {
33
33
  } catch {
34
34
  return false;
35
35
  }
36
- if (!record(event)) return false;
36
+ if (!record$1(event)) return false;
37
37
  if (event["type"] === "error" || event["type"] === "response.failed" || event["type"] === "response.incomplete") return false;
38
38
  if (event["type"] === "response.completed" || event["type"] === "response.done") {
39
- if (completed || !completedResponse(event["response"], model)) return false;
39
+ if (completed || !completedResponse$1(event["response"], model)) return false;
40
40
  completed = true;
41
41
  }
42
42
  } else if (line.startsWith("data:")) data.push(line.slice(5).replace(/^ /u, ""));
@@ -112,7 +112,7 @@ async function probeCodexResponses(request, createDispatcher = (proxyUrl) => pro
112
112
  const { value, done } = await reader.read();
113
113
  if (done) break;
114
114
  size += value.byteLength;
115
- if (size > MAX_PROBE_RESPONSE_BYTES) {
115
+ if (size > MAX_PROBE_RESPONSE_BYTES$1) {
116
116
  await reader.cancel();
117
117
  return {
118
118
  outcome: "incomplete",
@@ -125,7 +125,7 @@ async function probeCodexResponses(request, createDispatcher = (proxyUrl) => pro
125
125
  reader.releaseLock();
126
126
  }
127
127
  return {
128
- outcome: completedStream(new TextDecoder("utf-8", { fatal: true }).decode(Buffer.concat(chunks)), request.model) ? "completed" : "incomplete",
128
+ outcome: completedStream$1(new TextDecoder("utf-8", { fatal: true }).decode(Buffer.concat(chunks)), request.model) ? "completed" : "incomplete",
129
129
  httpStatus
130
130
  };
131
131
  } catch {
@@ -151,7 +151,7 @@ function result(status, reason, action) {
151
151
  function safeVersion(value) {
152
152
  return value !== null && value !== void 0 && /^v?\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/u.test(value) ? value : null;
153
153
  }
154
- function observed(evidence) {
154
+ function observed$1(evidence) {
155
155
  switch (evidence.outcome) {
156
156
  case "completed": return result("supported", "completed-response-for-selected-model", "This proves only the fixed standalone prompt; test the active Harness profile separately.");
157
157
  case "http-rejected": switch (evidence.httpStatus) {
@@ -295,7 +295,7 @@ var CodexCapabilityDiagnostics = class {
295
295
  };
296
296
  }
297
297
  if (evidence.httpStatus !== void 0) report.probe.httpStatus = evidence.httpStatus;
298
- checks.responses = observed(evidence);
298
+ checks.responses = observed$1(evidence);
299
299
  checks.transport = { ...checks.responses };
300
300
  if (evidence.outcome === "completed") {
301
301
  checks.oauth = result("supported", "authorized-completed-response", "Authorization succeeded for this model and fixed request at the recorded time only.");
@@ -369,6 +369,349 @@ async function runCapabilityCommand(args) {
369
369
  }
370
370
  }
371
371
  //#endregion
372
+ //#region src/auto-review-probe.ts
373
+ /** Fixed, standalone probe for the hidden Codex approval reviewer. */
374
+ /** Hidden reviewer route selected by the first-party Codex catalog. */
375
+ const CODEX_AUTO_REVIEW_MODEL = "codex-auto-review";
376
+ /** A response-reading limit, not a model output-token setting. */
377
+ const MAX_PROBE_RESPONSE_BYTES = 65536;
378
+ const instructions = "This is a capability diagnostic. Do not call tools or execute any action. Return one strict JSON assessment for the supplied synthetic approval request, including risk_level, user_authorization, outcome, and rationale.";
379
+ const input = "Synthetic approval request only; nothing will be executed. Planned action JSON: {\"type\":\"diagnostic-no-op\",\"sideEffects\":false}";
380
+ const assessmentSchema = {
381
+ type: "object",
382
+ additionalProperties: false,
383
+ properties: {
384
+ risk_level: {
385
+ type: "string",
386
+ enum: [
387
+ "low",
388
+ "medium",
389
+ "high",
390
+ "critical"
391
+ ]
392
+ },
393
+ user_authorization: {
394
+ type: "string",
395
+ enum: [
396
+ "unknown",
397
+ "low",
398
+ "medium",
399
+ "high"
400
+ ]
401
+ },
402
+ outcome: {
403
+ type: "string",
404
+ enum: ["allow", "deny"]
405
+ },
406
+ rationale: { type: "string" }
407
+ },
408
+ required: [
409
+ "risk_level",
410
+ "user_authorization",
411
+ "outcome",
412
+ "rationale"
413
+ ]
414
+ };
415
+ function record(value) {
416
+ return typeof value === "object" && value !== null && !Array.isArray(value);
417
+ }
418
+ function assessment(text) {
419
+ let value;
420
+ try {
421
+ value = JSON.parse(text);
422
+ } catch {
423
+ return false;
424
+ }
425
+ if (!record(value)) return false;
426
+ if (Object.keys(value).some((key) => ![
427
+ "risk_level",
428
+ "user_authorization",
429
+ "outcome",
430
+ "rationale"
431
+ ].includes(key))) return false;
432
+ if (![
433
+ "low",
434
+ "medium",
435
+ "high",
436
+ "critical"
437
+ ].includes(String(value["risk_level"]))) return false;
438
+ if (![
439
+ "unknown",
440
+ "low",
441
+ "medium",
442
+ "high"
443
+ ].includes(String(value["user_authorization"]))) return false;
444
+ if (!["allow", "deny"].includes(String(value["outcome"]))) return false;
445
+ return typeof value["rationale"] === "string";
446
+ }
447
+ function completedResponse(value) {
448
+ if (!record(value) || value["status"] !== "completed" || typeof value["model"] !== "string" || !Array.isArray(value["output"])) return void 0;
449
+ return value["output"].flatMap((item) => record(item) && item["type"] === "message" && item["role"] === "assistant" && Array.isArray(item["content"]) ? item["content"].flatMap((part) => record(part) && part["type"] === "output_text" && typeof part["text"] === "string" ? [part["text"]] : []) : []);
450
+ }
451
+ /** Inspect complete SSE frames and accept exactly one matching terminal response. */
452
+ function completedStream(text) {
453
+ let completed = false;
454
+ let terminalTexts;
455
+ const streamedTexts = [];
456
+ let data = [];
457
+ for (const line of text.split(/\r\n|\r|\n/u)) if (line === "") {
458
+ if (data.length === 0) continue;
459
+ const payload = data.join("\n");
460
+ data = [];
461
+ if (payload === "[DONE]") continue;
462
+ let event;
463
+ try {
464
+ event = JSON.parse(payload);
465
+ } catch {
466
+ return false;
467
+ }
468
+ if (!record(event) || event["type"] === "error" || event["type"] === "response.failed" || event["type"] === "response.incomplete") return false;
469
+ if (event["type"] === "response.output_text.done") {
470
+ if (typeof event["text"] !== "string") return false;
471
+ streamedTexts.push(event["text"]);
472
+ }
473
+ if (event["type"] === "response.completed" || event["type"] === "response.done") {
474
+ terminalTexts = completedResponse(event["response"]);
475
+ if (completed || terminalTexts === void 0) return false;
476
+ completed = true;
477
+ }
478
+ } else if (line.startsWith("data:")) data.push(line.slice(5).replace(/^ /u, ""));
479
+ if (!completed || data.length !== 0) return false;
480
+ const texts = terminalTexts.length > 0 ? terminalTexts : streamedTexts;
481
+ return texts.length === 1 && assessment(texts[0]);
482
+ }
483
+ /**
484
+ * Send one secret-free synthetic approval to the hidden reviewer model.
485
+ * The result is evidence only and never authorizes or executes an action.
486
+ * @param request - OAuth credential, explicit network policy, deadline, and optional cancellation.
487
+ * @param createDispatcher - owned connection factory; tests use an offline dispatcher.
488
+ * @returns bounded evidence without model-generated or provider error text.
489
+ */
490
+ async function probeCodexAutoReview(request, createDispatcher = (proxyUrl) => proxyUrl === void 0 ? new Agent() : new ProxyAgent(proxyUrl)) {
491
+ const dispatcher = createDispatcher(request.proxyUrl);
492
+ const controller = new AbortController();
493
+ let timedOut = false;
494
+ let cancelled = request.signal?.aborted ?? false;
495
+ const cancel = () => {
496
+ cancelled = true;
497
+ controller.abort();
498
+ };
499
+ request.signal?.addEventListener("abort", cancel, { once: true });
500
+ if (cancelled) controller.abort();
501
+ const timer = setTimeout(() => {
502
+ timedOut = true;
503
+ controller.abort();
504
+ }, request.timeoutMs);
505
+ let httpStatus;
506
+ try {
507
+ const response = await fetch(`${OPENAI_CODEX_BASE_URL}/responses`, {
508
+ dispatcher,
509
+ method: "POST",
510
+ redirect: "manual",
511
+ signal: controller.signal,
512
+ headers: {
513
+ authorization: `Bearer ${request.access}`,
514
+ "chatgpt-account-id": request.accountId,
515
+ "content-type": "application/json",
516
+ accept: "text/event-stream",
517
+ originator: "deepseek-harness"
518
+ },
519
+ body: JSON.stringify({
520
+ model: CODEX_AUTO_REVIEW_MODEL,
521
+ instructions,
522
+ input: [{
523
+ role: "user",
524
+ content: [{
525
+ type: "input_text",
526
+ text: input
527
+ }]
528
+ }],
529
+ text: { format: {
530
+ type: "json_schema",
531
+ name: "codex_auto_review_assessment",
532
+ strict: true,
533
+ schema: assessmentSchema
534
+ } },
535
+ stream: true,
536
+ store: false
537
+ })
538
+ });
539
+ httpStatus = response.status;
540
+ if (!response.ok) {
541
+ await response.body?.cancel();
542
+ return {
543
+ outcome: [
544
+ 400,
545
+ 401,
546
+ 403,
547
+ 404,
548
+ 405,
549
+ 422
550
+ ].includes(httpStatus) ? "http-rejected" : "transient",
551
+ httpStatus
552
+ };
553
+ }
554
+ const contentType = response.headers.get("content-type");
555
+ if (httpStatus !== 200 || contentType !== null && !contentType.toLowerCase().startsWith("text/event-stream") || response.body === null) {
556
+ await response.body?.cancel();
557
+ return {
558
+ outcome: "incomplete",
559
+ httpStatus
560
+ };
561
+ }
562
+ const reader = response.body.getReader();
563
+ const chunks = [];
564
+ let size = 0;
565
+ try {
566
+ while (true) {
567
+ const { value, done } = await reader.read();
568
+ if (done) break;
569
+ size += value.byteLength;
570
+ if (size > MAX_PROBE_RESPONSE_BYTES) {
571
+ await reader.cancel();
572
+ return {
573
+ outcome: "incomplete",
574
+ httpStatus
575
+ };
576
+ }
577
+ chunks.push(value);
578
+ }
579
+ } finally {
580
+ reader.releaseLock();
581
+ }
582
+ return {
583
+ outcome: completedStream(new TextDecoder("utf-8", { fatal: true }).decode(Buffer.concat(chunks))) ? "completed" : "incomplete",
584
+ httpStatus
585
+ };
586
+ } catch {
587
+ return {
588
+ outcome: cancelled ? "cancelled" : timedOut ? "timeout" : "network-error",
589
+ ...httpStatus === void 0 ? {} : { httpStatus }
590
+ };
591
+ } finally {
592
+ clearTimeout(timer);
593
+ request.signal?.removeEventListener("abort", cancel);
594
+ await dispatcher.destroy();
595
+ }
596
+ }
597
+ //#endregion
598
+ //#region src/auto-review-cli.ts
599
+ /** Opt-in diagnostic for the hidden Codex approval reviewer. */
600
+ function check(status, reason, action) {
601
+ return {
602
+ status,
603
+ reason,
604
+ action
605
+ };
606
+ }
607
+ function observed(evidence) {
608
+ switch (evidence.outcome) {
609
+ case "completed": return check("supported", "completed-structured-review", "The OAuth route accepted the hidden reviewer and returned its approval schema; this does not enable DSH approval integration.");
610
+ case "http-rejected": return check("rejected", `http-${String(evidence.httpStatus ?? "rejected")}`, "The supported OAuth route rejected this hidden reviewer request; keep automatic approval disabled.");
611
+ case "transient": return check("unknown", "transient-or-redirect-response", "Check network, quota, or service availability before explicitly retrying.");
612
+ case "incomplete": return check("unknown", "no-complete-structured-review", "HTTP success without one matching structured assessment is not capability evidence.");
613
+ case "timeout": return check("unknown", "probe-deadline", "The diagnostic exceeded its deadline; no approval capability was established.");
614
+ case "cancelled": return check("unknown", "probe-cancelled", "The diagnostic was cancelled; no approval capability was established.");
615
+ case "network-error": return check("unknown", "network-or-stream-error", "Check the network or pass an explicit --proxy; no server decision was confirmed.");
616
+ }
617
+ }
618
+ /** Run the standalone reviewer probe without booting Harness or changing settings. */
619
+ async function runAutoReviewProbeCommand(args, deps = {
620
+ diagnose: diagnoseOpenAICodex,
621
+ credentials: new OpenAICodexCredentialStore(),
622
+ probe: probeCodexAutoReview,
623
+ now: Date.now
624
+ }) {
625
+ let json = false;
626
+ let proxyUrl;
627
+ let timeoutMs = 3e4;
628
+ const seen = /* @__PURE__ */ new Set();
629
+ const invalid = () => {
630
+ process.stderr.write("Usage: dsh-codex-connect auto-review-probe [--proxy <http(s)-origin>] [--timeout-ms <1..60000>] [--json]\n");
631
+ return 2;
632
+ };
633
+ for (let index = 0; index < args.length; index += 1) {
634
+ const flag = args[index];
635
+ if (seen.has(flag)) return invalid();
636
+ seen.add(flag);
637
+ if (flag === "--json") json = true;
638
+ else if (flag === "--proxy" || flag === "--timeout-ms") {
639
+ const value = args[++index];
640
+ if (value === void 0 || value.startsWith("--")) return invalid();
641
+ if (flag === "--proxy") {
642
+ proxyUrl = normalizeOpenAICodexProxyUrl(value);
643
+ if (proxyUrl === void 0) return invalid();
644
+ } else {
645
+ if (!/^\d+$/u.test(value) || Number(value) < 1 || Number(value) > 6e4) return invalid();
646
+ timeoutMs = Number(value);
647
+ }
648
+ } else return invalid();
649
+ }
650
+ const local = await deps.diagnose();
651
+ const runtime = local.compatibility.status === "compatible" ? check("supported", "declared-host-versions-match", "Installed package versions satisfy the probe prerequisites; this is not active-profile validation.") : check(local.compatibility.status === "incompatible" ? "rejected" : "unknown", "runtime-compatibility-unavailable", "Install the supported Codex Connect and DSH package set before probing.");
652
+ let oauth = local.credentialFile.state === "owner-only" ? check("unknown", "credential-metadata-only", "An owner-only file does not prove authorization; the explicit probe reads its unexpired stored credential.") : check("rejected", "credential-file-unusable", "Sign in or repair the owner-only credential file before probing.");
653
+ let reviewer = check("unknown", "not-probed", "Run this command explicitly only when one fixed diagnostic request is acceptable.");
654
+ let probe = { state: "skipped" };
655
+ if (runtime.status === "supported" && oauth.status !== "rejected") {
656
+ let credential;
657
+ try {
658
+ credential = await deps.credentials.read(OPENAI_CODEX_PROVIDER);
659
+ } catch {
660
+ oauth = check("rejected", "credential-unreadable", "Repair the credential file or sign in again; diagnostic output omits parser details.");
661
+ }
662
+ if (credential?.type !== "oauth" || typeof credential.accountId !== "string") {
663
+ if (oauth.reason !== "credential-unreadable") oauth = check("rejected", "credential-missing", "Sign in before explicitly probing the hidden reviewer.");
664
+ } else if (credential.expires <= deps.now()) oauth = check("unknown", "access-token-expired", "Use the normal sign-in or refresh flow, then repeat the probe; diagnostics never refresh credentials.");
665
+ else {
666
+ let evidence;
667
+ try {
668
+ evidence = await deps.probe({
669
+ access: credential.access,
670
+ accountId: credential.accountId,
671
+ proxyUrl,
672
+ timeoutMs
673
+ });
674
+ } catch {
675
+ evidence = { outcome: "network-error" };
676
+ }
677
+ probe = {
678
+ state: "fresh",
679
+ ...evidence.httpStatus === void 0 ? {} : { httpStatus: evidence.httpStatus }
680
+ };
681
+ reviewer = observed(evidence);
682
+ if (evidence.outcome === "completed") oauth = check("supported", "authorized-completed-review", "Authorization succeeded for this fixed reviewer request at the recorded time only.");
683
+ else if (evidence.httpStatus === 401) oauth = check("rejected", "http-401", "Sign in again, then explicitly repeat the probe.");
684
+ }
685
+ }
686
+ const report = {
687
+ schemaVersion: 1,
688
+ package: "dsh-codex-connect",
689
+ version: CODEX_CONNECT_VERSION,
690
+ scope: "auto-review-route-only",
691
+ model: CODEX_AUTO_REVIEW_MODEL,
692
+ network: proxyUrl === void 0 ? "direct" : "explicit-proxy",
693
+ checks: {
694
+ runtime,
695
+ oauth,
696
+ reviewer
697
+ },
698
+ probe
699
+ };
700
+ process.stdout.write(json ? `${JSON.stringify(report)}\n` : [
701
+ `Codex Connect ${report.version}: hidden approval-review capability probe`,
702
+ "Scope: one synthetic no-op; no command is executed and no approval integration is enabled.",
703
+ `Model: ${report.model}; network: ${report.network}; probe: ${report.probe.state}`,
704
+ ...Object.entries(report.checks).map(([id, value]) => `${id}: ${value.status} (${value.reason})\n ${value.action}`),
705
+ ""
706
+ ].join("\n"));
707
+ const primary = [
708
+ runtime,
709
+ oauth,
710
+ reviewer
711
+ ];
712
+ return primary.some((value) => value.status === "rejected") ? 1 : primary.some((value) => value.status === "unknown") ? 2 : 0;
713
+ }
714
+ //#endregion
372
715
  //#region src/bin.ts
373
716
  /** Standalone credential CLI for the optional OpenAI Codex bundle. */
374
717
  const JSON_SCHEMA_VERSION = 1;
@@ -435,8 +778,10 @@ function printHelp() {
435
778
  " dsh-codex-connect trusted-origins [--json]",
436
779
  " dsh-codex-connect untrust-origin <origin>",
437
780
  " dsh-codex-connect capabilities [--model <catalog-id>] [--probe] [--proxy <http(s)-origin>] [--timeout-ms <1..60000>] [--json]",
781
+ " dsh-codex-connect auto-review-probe [--proxy <http(s)-origin>] [--timeout-ms <1..60000>] [--json]",
438
782
  "",
439
783
  " doctor inspect secret-free runtime and OAuth file metadata",
784
+ " auto-review-probe test the hidden approval reviewer with one synthetic no-op",
440
785
  " login sign in with a separate ChatGPT OAuth session",
441
786
  " logout remove the dsh credential without changing ~/.codex",
442
787
  " migrate-history find or repair Alpha 4.10 private search events (dry-run by default)",
@@ -445,7 +790,7 @@ function printHelp() {
445
790
  " trusted-origins list the currently allowed browser origins",
446
791
  " untrust-origin remove one exact browser origin from the allowlist",
447
792
  " --device-code use headless device-code login (login only)",
448
- " --json emit one JSON document (doctor/status/trusted-origins/migrate-history)",
793
+ " --json emit one JSON document (doctor/status/capabilities/auto-review-probe/trusted-origins/migrate-history)",
449
794
  ""
450
795
  ].join("\n"));
451
796
  }
@@ -483,6 +828,7 @@ async function run(argv) {
483
828
  }
484
829
  const [rawAction, ...flags] = argv;
485
830
  if (rawAction === "capabilities") return runCapabilityCommand(flags);
831
+ if (rawAction === "auto-review-probe") return runAutoReviewProbeCommand(flags);
486
832
  if (![
487
833
  "doctor",
488
834
  "login",
package/lib/client.js CHANGED
@@ -1311,7 +1311,8 @@ window.__ModuleLoader__.load({
1311
1311
  "model-visibility",
1312
1312
  "proxy-connection",
1313
1313
  "models-account",
1314
- "context-budget"
1314
+ "context-budget",
1315
+ "auto-review-probe"
1315
1316
  ];
1316
1317
  function isHighlightKind(value) {
1317
1318
  return typeof value === "string" && HIGHLIGHT_KINDS.includes(value);
@@ -1818,7 +1819,8 @@ window.__ModuleLoader__.load({
1818
1819
  "model-visibility": "updateHighlightModelVisibility",
1819
1820
  "proxy-connection": "updateHighlightProxyConnection",
1820
1821
  "models-account": "updateHighlightModelsAccount",
1821
- "context-budget": "updateHighlightContextBudget"
1822
+ "context-budget": "updateHighlightContextBudget",
1823
+ "auto-review-probe": "updateHighlightAutoReviewProbe"
1822
1824
  };
1823
1825
  const compatibilityTitleKeys = {
1824
1826
  compatible: "compatibilityCompatibleTitle",
@@ -3383,6 +3385,7 @@ window.__ModuleLoader__.load({
3383
3385
  updateHighlightProxyConnection: "Added opt-in Codex proxy detection with explicit confirmation and a visible direct-connection fallback.",
3384
3386
  updateHighlightModelsAccount: "Added an Openai-Codex account card in Models settings for authorization, quota, and shared plugin settings.",
3385
3387
  updateHighlightContextBudget: "Added bounded per-model context budget controls while preserving each catalog default until you save an override.",
3388
+ updateHighlightAutoReviewProbe: "Added an explicit, synthetic probe for checking whether the hidden Codex approval reviewer is available without enabling it.",
3386
3389
  viewTechnicalDetails: "View technical details",
3387
3390
  hideTechnicalDetails: "Hide technical details",
3388
3391
  technicalDetailsHeading: "Technical changes",
@@ -3624,6 +3627,7 @@ window.__ModuleLoader__.load({
3624
3627
  updateHighlightProxyConnection: "增加可选的 Codex 代理检测,启用前需要明确确认,并始终保留直连回退入口。",
3625
3628
  updateHighlightModelsAccount: "在模型设置中增加 Openai-Codex 账户卡,用于授权、查看额度和打开共享插件设置。",
3626
3629
  updateHighlightContextBudget: "增加有范围限制的逐模型上下文预算设置;保存覆盖值前继续使用各模型的目录默认值。",
3630
+ updateHighlightAutoReviewProbe: "增加显式的合成探针,用于检查隐藏的 Codex 审批 reviewer 是否可用,但不会启用该能力。",
3627
3631
  viewTechnicalDetails: "查看完整技术说明",
3628
3632
  hideTechnicalDetails: "收起技术说明",
3629
3633
  technicalDetailsHeading: "技术变更",
@@ -4809,7 +4813,7 @@ window.__ModuleLoader__.load({
4809
4813
  }
4810
4814
  //#endregion
4811
4815
  //#region src/version.ts
4812
- const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.22";
4816
+ const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.23";
4813
4817
  //#endregion
4814
4818
  //#region src/client/OpenAICodexModelsCard.tsx
4815
4819
  /** Compact Models account entry with quota disclosure and shared configuration. */
@@ -5045,6 +5049,7 @@ window.__ModuleLoader__.load({
5045
5049
  "locale",
5046
5050
  "connection",
5047
5051
  "remote",
5052
+ "remote.session",
5048
5053
  "settingsScope",
5049
5054
  "sessions"
5050
5055
  ];
package/lib/index.d.ts CHANGED
@@ -573,7 +573,7 @@ declare const OPENAI_CODEX_FAST_MODE_PATH = "/plugins/dsh-openai-codex/fast-mode
573
573
  declare const OPENAI_CODEX_UPDATE_PATH = "/openai-codex/update";
574
574
  //#endregion
575
575
  //#region src/update.d.ts
576
- type OpenAICodexUpdateHighlightKind = 'trusted-origins' | 'runtime-compatibility' | 'quota-fast-mode' | 'dsh-rc7' | 'search-stability' | 'image-generation' | 'oauth-history' | 'model-visibility' | 'proxy-connection' | 'models-account' | 'context-budget';
576
+ type OpenAICodexUpdateHighlightKind = 'trusted-origins' | 'runtime-compatibility' | 'quota-fast-mode' | 'dsh-rc7' | 'search-stability' | 'image-generation' | 'oauth-history' | 'model-visibility' | 'proxy-connection' | 'models-account' | 'context-budget' | 'auto-review-probe';
577
577
  interface OpenAICodexUpdateHighlight {
578
578
  version: string;
579
579
  kind: OpenAICodexUpdateHighlightKind;
package/lib/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { $ as OPENAI_CODEX_PROXY_PROBE_TIMEOUT_MS, A as openAICodexConflictMessage, B as DSH_PLUGIN_API_PACKAGES, C as OpenAICodexTransport, D as IMAGE_GENERATE_TOOL_NAME, Dt as loginOpenAICodex, E as VIEW_IMAGE_TOOL_NAME, Et as readOpenAICodexRateLimits, F as parseOpenAICodexUpdateResult, G as assessCompatibility, H as SUPPORTED_DSH_PLUGIN_API_VERSION, I as parseOpenAICodexVersion, K as detectCompatibility, L as COMPATIBILITY_CONTRACT, M as OPENAI_CODEX_UPDATE_PATH, Mt as OPENAI_CODEX_PROVIDER, N as checkForOpenAICodexUpdate, Nt as OpenAICodexCredentialStore, O as assertNoOpenAICodexProviderConflict, Ot as logoutOpenAICodex, P as compareOpenAICodexVersions, Pt as openAICodexAuthPath, Q as OPENAI_CODEX_PROXY_CANDIDATE_LIMIT, R as COMPATIBILITY_PACKAGES, S as OPENAI_CODEX_TRANSPORT_SERVICE, T as isOpenAICodexTransportError, Tt as parseOpenAICodexUsage, U as SUPPORTED_NODE_RANGE, V as PI_AI_PACKAGE, W as SUPPORTED_PI_AI_RANGE, X as OPENAI_CODEX_PROXY_TEST_PATH, Y as OPENAI_CODEX_PROXY_DETECT_PATH, Z as OPENAI_CODEX_LOCAL_PROXY_CANDIDATES, _ as OPENAI_CODEX_IMAGE_MAX_RESPONSE_BYTES, _t as OPENAI_CODEX_FAST_MODE_PATH, a as name, at as DEFAULT_OPENAI_CODEX_SEARCH_CONTEXT_SIZE, b as OPENAI_CODEX_TRANSPORT_API_VERSION, bt as OPENAI_CODEX_FAST_MODE_MAX_SESSION_ID_LENGTH, c as migrateOpenAICodexSearchHistory, ct as DEFAULT_OPENAI_CODEX_SEARCH_MODEL, d as OPENAI_CODEX_SEARCH_URL, dt as decodeOpenAICodexSettings, et as OPENAI_CODEX_PROXY_PROBE_URL, f as OpenAICodexSearchProvider, ft as isValidOpenAICodexContextWindowOverrides, g as OPENAI_CODEX_IMAGE_MAX_ERROR_BYTES, gt as resolveOpenAICodexSettings, h as OPENAI_CODEX_IMAGE_MAX_COUNT, ht as resolveOpenAICodexProxyUrl, i as inject, it as DEFAULT_OPENAI_CODEX_PROXY_URL, jt as OPENAI_CODEX_AUTH_FILENAME, k as diagnoseOpenAICodex, kt as openAICodexAuthStatus, l as OPENAI_CODEX_BASE_URL, lt as DEFAULT_OPENAI_CODEX_SETTINGS, m as OPENAI_CODEX_IMAGE_GENERATION_URL, n as OPENAI_CODEX_SETTINGS_NS, nt as detectOpenAICodexProxies, o as OPENAI_CODEX_HISTORY_BACKUP_SUFFIX, ot as DEFAULT_OPENAI_CODEX_SEARCH_MAX_OUTPUT_TOKENS, p as mapOpenAICodexSearchResponse, pt as isValidOpenAICodexProxyUrl, q as evaluateCompatibility, r as apply, rt as listOpenAICodexProxyCandidates, s as OPENAI_CODEX_SEARCH_MODEL_REQUEST_EVENT, st as DEFAULT_OPENAI_CODEX_SEARCH_MODE, t as Config, tt as OpenAICodexProxyManager, u as OPENAI_CODEX_SEARCH_PROVIDER, ut as OPENAI_CODEX_SETTINGS_NAMESPACE, v as OPENAI_CODEX_IMAGE_PROMPT_MAX_LENGTH, vt as FastModeRegistry, w as OpenAICodexTransportError, wt as OPENAI_CODEX_USAGE_URL, x as OPENAI_CODEX_TRANSPORT_ERROR_CODES, xt as isFastModeSessionId, y as OPENAI_CODEX_IMAGE_REQUEST_TIMEOUT_MS, yt as OPENAI_CODEX_FAST_MODE_MAX_SESSIONS, z as COMPATIBILITY_SCHEMA_VERSION } from "./src-kwF-uZCG.js";
1
+ import { $ as OPENAI_CODEX_PROXY_PROBE_TIMEOUT_MS, A as openAICodexConflictMessage, B as DSH_PLUGIN_API_PACKAGES, C as OpenAICodexTransport, D as IMAGE_GENERATE_TOOL_NAME, Dt as loginOpenAICodex, E as VIEW_IMAGE_TOOL_NAME, Et as readOpenAICodexRateLimits, F as parseOpenAICodexUpdateResult, G as assessCompatibility, H as SUPPORTED_DSH_PLUGIN_API_VERSION, I as parseOpenAICodexVersion, K as detectCompatibility, L as COMPATIBILITY_CONTRACT, M as OPENAI_CODEX_UPDATE_PATH, Mt as OPENAI_CODEX_PROVIDER, N as checkForOpenAICodexUpdate, Nt as OpenAICodexCredentialStore, O as assertNoOpenAICodexProviderConflict, Ot as logoutOpenAICodex, P as compareOpenAICodexVersions, Pt as openAICodexAuthPath, Q as OPENAI_CODEX_PROXY_CANDIDATE_LIMIT, R as COMPATIBILITY_PACKAGES, S as OPENAI_CODEX_TRANSPORT_SERVICE, T as isOpenAICodexTransportError, Tt as parseOpenAICodexUsage, U as SUPPORTED_NODE_RANGE, V as PI_AI_PACKAGE, W as SUPPORTED_PI_AI_RANGE, X as OPENAI_CODEX_PROXY_TEST_PATH, Y as OPENAI_CODEX_PROXY_DETECT_PATH, Z as OPENAI_CODEX_LOCAL_PROXY_CANDIDATES, _ as OPENAI_CODEX_IMAGE_MAX_RESPONSE_BYTES, _t as OPENAI_CODEX_FAST_MODE_PATH, a as name, at as DEFAULT_OPENAI_CODEX_SEARCH_CONTEXT_SIZE, b as OPENAI_CODEX_TRANSPORT_API_VERSION, bt as OPENAI_CODEX_FAST_MODE_MAX_SESSION_ID_LENGTH, c as migrateOpenAICodexSearchHistory, ct as DEFAULT_OPENAI_CODEX_SEARCH_MODEL, d as OPENAI_CODEX_SEARCH_URL, dt as decodeOpenAICodexSettings, et as OPENAI_CODEX_PROXY_PROBE_URL, f as OpenAICodexSearchProvider, ft as isValidOpenAICodexContextWindowOverrides, g as OPENAI_CODEX_IMAGE_MAX_ERROR_BYTES, gt as resolveOpenAICodexSettings, h as OPENAI_CODEX_IMAGE_MAX_COUNT, ht as resolveOpenAICodexProxyUrl, i as inject, it as DEFAULT_OPENAI_CODEX_PROXY_URL, jt as OPENAI_CODEX_AUTH_FILENAME, k as diagnoseOpenAICodex, kt as openAICodexAuthStatus, l as OPENAI_CODEX_BASE_URL, lt as DEFAULT_OPENAI_CODEX_SETTINGS, m as OPENAI_CODEX_IMAGE_GENERATION_URL, n as OPENAI_CODEX_SETTINGS_NS, nt as detectOpenAICodexProxies, o as OPENAI_CODEX_HISTORY_BACKUP_SUFFIX, ot as DEFAULT_OPENAI_CODEX_SEARCH_MAX_OUTPUT_TOKENS, p as mapOpenAICodexSearchResponse, pt as isValidOpenAICodexProxyUrl, q as evaluateCompatibility, r as apply, rt as listOpenAICodexProxyCandidates, s as OPENAI_CODEX_SEARCH_MODEL_REQUEST_EVENT, st as DEFAULT_OPENAI_CODEX_SEARCH_MODE, t as Config, tt as OpenAICodexProxyManager, u as OPENAI_CODEX_SEARCH_PROVIDER, ut as OPENAI_CODEX_SETTINGS_NAMESPACE, v as OPENAI_CODEX_IMAGE_PROMPT_MAX_LENGTH, vt as FastModeRegistry, w as OpenAICodexTransportError, wt as OPENAI_CODEX_USAGE_URL, x as OPENAI_CODEX_TRANSPORT_ERROR_CODES, xt as isFastModeSessionId, y as OPENAI_CODEX_IMAGE_REQUEST_TIMEOUT_MS, yt as OPENAI_CODEX_FAST_MODE_MAX_SESSIONS, z as COMPATIBILITY_SCHEMA_VERSION } from "./src-ByKP_wn9.js";
2
2
  export { COMPATIBILITY_CONTRACT, COMPATIBILITY_PACKAGES, COMPATIBILITY_SCHEMA_VERSION, Config, DEFAULT_OPENAI_CODEX_PROXY_URL, DEFAULT_OPENAI_CODEX_SEARCH_CONTEXT_SIZE, DEFAULT_OPENAI_CODEX_SEARCH_MAX_OUTPUT_TOKENS, DEFAULT_OPENAI_CODEX_SEARCH_MODE, DEFAULT_OPENAI_CODEX_SEARCH_MODEL, DEFAULT_OPENAI_CODEX_SETTINGS, DSH_PLUGIN_API_PACKAGES, FastModeRegistry, FastModeRegistry as OpenAICodexFastModeRegistry, IMAGE_GENERATE_TOOL_NAME, OPENAI_CODEX_AUTH_FILENAME, OPENAI_CODEX_BASE_URL, OPENAI_CODEX_FAST_MODE_MAX_SESSIONS, OPENAI_CODEX_FAST_MODE_MAX_SESSION_ID_LENGTH, OPENAI_CODEX_FAST_MODE_PATH, OPENAI_CODEX_HISTORY_BACKUP_SUFFIX, OPENAI_CODEX_IMAGE_GENERATION_URL, OPENAI_CODEX_IMAGE_MAX_COUNT, OPENAI_CODEX_IMAGE_MAX_ERROR_BYTES, OPENAI_CODEX_IMAGE_MAX_RESPONSE_BYTES, OPENAI_CODEX_IMAGE_PROMPT_MAX_LENGTH, OPENAI_CODEX_IMAGE_REQUEST_TIMEOUT_MS, OPENAI_CODEX_LOCAL_PROXY_CANDIDATES, OPENAI_CODEX_PROVIDER, OPENAI_CODEX_PROXY_CANDIDATE_LIMIT, OPENAI_CODEX_PROXY_DETECT_PATH, OPENAI_CODEX_PROXY_PROBE_TIMEOUT_MS, OPENAI_CODEX_PROXY_PROBE_URL, OPENAI_CODEX_PROXY_TEST_PATH, OPENAI_CODEX_SEARCH_MODEL_REQUEST_EVENT, OPENAI_CODEX_SEARCH_PROVIDER, OPENAI_CODEX_SEARCH_URL, OPENAI_CODEX_SETTINGS_NAMESPACE, OPENAI_CODEX_SETTINGS_NS, OPENAI_CODEX_TRANSPORT_API_VERSION, OPENAI_CODEX_TRANSPORT_ERROR_CODES, OPENAI_CODEX_TRANSPORT_SERVICE, OPENAI_CODEX_UPDATE_PATH, OPENAI_CODEX_USAGE_URL, OpenAICodexCredentialStore, OpenAICodexProxyManager, OpenAICodexSearchProvider, OpenAICodexTransport, OpenAICodexTransportError, PI_AI_PACKAGE, SUPPORTED_DSH_PLUGIN_API_VERSION, SUPPORTED_NODE_RANGE, SUPPORTED_PI_AI_RANGE, VIEW_IMAGE_TOOL_NAME, apply, assertNoOpenAICodexProviderConflict, assessCompatibility, checkForOpenAICodexUpdate, compareOpenAICodexVersions, decodeOpenAICodexSettings, detectCompatibility, detectOpenAICodexProxies, diagnoseOpenAICodex, evaluateCompatibility, inject, isFastModeSessionId, isOpenAICodexTransportError, isValidOpenAICodexContextWindowOverrides, isValidOpenAICodexProxyUrl, listOpenAICodexProxyCandidates, loginOpenAICodex, logoutOpenAICodex, mapOpenAICodexSearchResponse, migrateOpenAICodexSearchHistory, name, openAICodexAuthPath, openAICodexAuthStatus, openAICodexConflictMessage, parseOpenAICodexUpdateResult, parseOpenAICodexUsage, parseOpenAICodexVersion, readOpenAICodexRateLimits, resolveOpenAICodexProxyUrl, resolveOpenAICodexSettings };
@@ -1838,7 +1838,8 @@ const HIGHLIGHT_KINDS = [
1838
1838
  "model-visibility",
1839
1839
  "proxy-connection",
1840
1840
  "models-account",
1841
- "context-budget"
1841
+ "context-budget",
1842
+ "auto-review-probe"
1842
1843
  ];
1843
1844
  function isHighlightKind(value) {
1844
1845
  return typeof value === "string" && HIGHLIGHT_KINDS.includes(value);
@@ -2501,7 +2502,7 @@ function registerOpenAICodexOriginalImageRoute(ctx, trustedOrigins, assets) {
2501
2502
  }
2502
2503
  //#endregion
2503
2504
  //#region src/version.ts
2504
- const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.22";
2505
+ const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.23";
2505
2506
  //#endregion
2506
2507
  //#region src/doctor.ts
2507
2508
  /** Secret-free diagnostics and duplicate-provider guidance. */
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "dsh-codex-connect",
3
3
  "displayName": "Codex Connect",
4
4
  "description": "ChatGPT OAuth and Codex models for DeepSeek Harness.",
5
- "version": "0.1.0-alpha.4.22",
5
+ "version": "0.1.0-alpha.4.23",
6
6
  "author": "Frank Song",
7
7
  "contributors": [
8
8
  "Yan-Zero (original dsh-codex author)"