dsh-codex-connect 0.1.0-alpha.4.25 → 0.1.0-alpha.4.26
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 +16 -8
- package/README.i18n.yaml +2 -2
- package/README.md +8 -4
- package/compatibility.json +1 -1
- package/docs/README.zh.md +8 -4
- package/docs/design.i18n.yaml +2 -2
- package/docs/design.md +4 -2
- package/docs/design.zh.md +4 -2
- package/lib/bin.js +2 -2
- package/lib/client.js +1 -1
- package/lib/index.d.ts +33 -5
- package/lib/index.js +2 -2
- package/lib/{src-Di2xxpDv.js → src-FSN1b9Tk.js} +354 -54
- package/package.json +75 -75
package/INSTALL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Installation Runbook for CLI Agents
|
|
2
2
|
|
|
3
|
-
Alpha 4.
|
|
3
|
+
Alpha 4.26 is verified with DSH `0.1.2-rc.1` and its declared pi-ai range `^0.84.2`.
|
|
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
|
|
|
@@ -23,13 +23,14 @@ Check `dsh --version` before changing the requested profile. Use `dsh --help` to
|
|
|
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
25
|
| `0.1.2-alpha.2` | `0.1.0-alpha.4.23` |
|
|
26
|
+
| `0.1.2-rc.1` | `0.1.0-alpha.4.26` |
|
|
26
27
|
| `0.1.2-alpha.5` | `0.1.0-alpha.4.25` |
|
|
27
28
|
|
|
28
29
|
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.
|
|
29
30
|
|
|
30
|
-
Alpha 4.
|
|
31
|
+
Alpha 4.26's verified contract is DSH plugin API packages `0.1.2-rc.1`, `@earendil-works/pi-ai` `^0.84.2`, and Node.js `^22.19.0 || >=24.0.0`. Alpha 4.25 remains the verified choice for DSH `0.1.2-alpha.5`, Alpha 4.23 remains the verified choice for DSH `0.1.2-alpha.2`, Alpha 4.21 remains the verified choice for DSH `0.1.1-rc.2`, and 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.
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
The Alpha 4.26 row reflects a fresh isolated installation and runtime probe. Historical rows remain the repository's existing verification record. This guidance does not change upstream DSH behavior or resolve [Issue #64](https://github.com/franksong2702/dsh-codex-connect/issues/64).
|
|
33
34
|
|
|
34
35
|
### Install the selected version and validate
|
|
35
36
|
|
|
@@ -52,23 +53,30 @@ These choices reflect the repository's existing verification record, not a new i
|
|
|
52
53
|
dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.23
|
|
53
54
|
```
|
|
54
55
|
|
|
56
|
+
For DSH `0.1.2-rc.1`, use Alpha 4.26:
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.26
|
|
60
|
+
```
|
|
61
|
+
|
|
55
62
|
For DSH `0.1.2-alpha.5`, use Alpha 4.25:
|
|
56
63
|
|
|
57
64
|
```sh
|
|
58
65
|
dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.25
|
|
59
66
|
```
|
|
60
67
|
|
|
61
|
-
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, `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,
|
|
68
|
+
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, `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, `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.25'` only for the DSH `0.1.2-alpha.5` combination, or `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.26'` only for the DSH `0.1.2-rc.1` combination.
|
|
62
69
|
|
|
63
|
-
3. Run `dsh
|
|
64
|
-
4.
|
|
65
|
-
5.
|
|
70
|
+
3. Run `dsh web --help` once to compose the installed profile without starting the server. DSH `0.1.2-rc.1` prepares profile plugin dependency fallback during this step.
|
|
71
|
+
4. Run `dsh --profile web --dump-config` and require exactly one `llm-openai-codex` row loading `dsh-codex-connect`.
|
|
72
|
+
5. Confirm the effective `agent-default-model` and `web.searchProvider` values are unchanged from before installation.
|
|
73
|
+
6. Run secret-free diagnostics:
|
|
66
74
|
|
|
67
75
|
```sh
|
|
68
76
|
dsh plugin --profile web exec dsh-codex-connect doctor
|
|
69
77
|
```
|
|
70
78
|
|
|
71
|
-
|
|
79
|
+
7. 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.
|
|
72
80
|
|
|
73
81
|
Alpha 4.25 offers the same account actions in **Settings → Models → Openai-Codex**, plus a shared **More settings** dialog for model visibility, proxy, search, image, context-budget, and Auto-review controls. The original Plugin settings entry remains available; neither entry automatically starts login or changes model/search defaults.
|
|
74
82
|
|
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:
|
|
6
|
-
docs/README.zh.md:
|
|
5
|
+
README.md: c2fb988676d46f1d05d96b2e665df6c4b0505fce
|
|
6
|
+
docs/README.zh.md: 54386abdfc31e6d3a243892ee9f8508642033b59
|
package/README.md
CHANGED
|
@@ -18,19 +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 quick start targets DSH `0.1.2-
|
|
21
|
+
This quick start targets DSH `0.1.2-rc.1` with Codex Connect Alpha 4.26. Check `dsh --version` first. For DSH `0.1.2-alpha.5`, `0.1.2-alpha.2`, `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@0.1.0-alpha.4.
|
|
26
|
+
dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.26
|
|
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
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.
|
|
33
|
+
### What's new in Alpha 4.26
|
|
34
|
+
|
|
35
|
+
- Add verified compatibility with DSH `0.1.2-rc.1`, including an isolated install, profile composition, diagnostics, model-catalog, and disposal canary.
|
|
36
|
+
|
|
37
|
+
### Previously in Alpha 4.25
|
|
34
38
|
|
|
35
39
|
- Show the exact 5-hour and weekly quota windows returned by ChatGPT for the selected Codex model. Missing windows stay hidden, Spark remains separate, and plan names do not suppress server data.
|
|
36
40
|
- Separate verified compatibility from maintainer follow-up. The settings card no longer treats missing verification as a known runtime failure or recommends a plugin downgrade.
|
|
@@ -322,7 +326,7 @@ The command sends one fixed, synthetic no-op to the hidden reviewer through the
|
|
|
322
326
|
|
|
323
327
|
## Compatibility and security boundary
|
|
324
328
|
|
|
325
|
-
- Alpha 4.
|
|
329
|
+
- Alpha 4.26 is verified with DSH plugin API packages `0.1.2-rc.1`, `@earendil-works/pi-ai` `^0.84.2`, and Node.js `^22.19.0 || >=24.0.0`. Alpha 4.25 remains the verified choice for DSH `0.1.2-alpha.5`, Alpha 4.23 remains the verified choice for DSH `0.1.2-alpha.2`, and 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.
|
|
326
330
|
- 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.
|
|
327
331
|
- 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.
|
|
328
332
|
- 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/compatibility.json
CHANGED
package/docs/README.zh.md
CHANGED
|
@@ -18,19 +18,23 @@
|
|
|
18
18
|
|
|
19
19
|
## 五分钟快速开始
|
|
20
20
|
|
|
21
|
-
本快速指南适用于 DSH `0.1.2-
|
|
21
|
+
本快速指南适用于 DSH `0.1.2-rc.1` 与 Codex Connect Alpha 4.26。请先运行 `dsh --version`。如果使用 DSH `0.1.2-alpha.5`、`0.1.2-alpha.2`、`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@0.1.0-alpha.4.
|
|
26
|
+
dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.26
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
预期结果:包被加入该 profile。这个动作不会更改 profile 的默认模型或全局搜索路由。
|
|
30
30
|
|
|
31
31
|
请使用上面的精确版本,确保已验证的 DSH 与插件组合可以复现。`alpha` 是会移动的 npm 标签,不是兼容性保证。
|
|
32
32
|
|
|
33
|
-
### Alpha 4.
|
|
33
|
+
### Alpha 4.26 更新内容
|
|
34
|
+
|
|
35
|
+
- 新增对 DSH `0.1.2-rc.1` 的已验证兼容性,覆盖隔离安装、profile 组合、诊断、模型目录和卸载清理 canary。
|
|
36
|
+
|
|
37
|
+
### Alpha 4.25 既有内容
|
|
34
38
|
|
|
35
39
|
- 显示 ChatGPT 为当前 Codex 模型实际返回的 5 小时和每周额度窗口。缺少的窗口不会凭空出现,Spark 额度保持独立,也不会因套餐名称而隐藏服务端数据。
|
|
36
40
|
- 将“当前组合是否已验证”和“是否需要提醒维护者”分开判断。缺少验证记录不再被说成已知运行失败,也不会建议降级插件。
|
|
@@ -324,7 +328,7 @@ dsh plugin --profile web exec dsh-codex-connect auto-review-probe --json
|
|
|
324
328
|
|
|
325
329
|
## 兼容性与安全边界
|
|
326
330
|
|
|
327
|
-
- Alpha 4.
|
|
331
|
+
- Alpha 4.26 已与 DSH 插件 API packages `0.1.2-rc.1`、`@earendil-works/pi-ai` `^0.84.2` 和 Node.js `^22.19.0 || >=24.0.0` 完成验证。Alpha 4.25 仍是 DSH `0.1.2-alpha.5` 的已验证选择;Alpha 4.23 仍是 DSH `0.1.2-alpha.2` 的已验证选择;Alpha 4.21 仍与 DSH `0.1.1-rc.2` 和 pi-ai `0.82.1` 保持已验证状态。[verified-compatibility.json](../verified-compatibility.json) 记录精确组合;安装命令见 [INSTALL.md](../INSTALL.md)。
|
|
328
332
|
- 新版 DSH 将原来的 client runtime 拆分为 Session Controller、Settings、Store 和 Renderer 包。Codex Connect 通过这些公开接口接入设置和图片操作。规范化预览的编码与尺寸由 DSH 决定;Codex Connect 另行保留字节完全一致的原图。
|
|
329
333
|
- 升级时请将 DSH 插件 API packages 与 `@earendil-works/pi-ai` 作为一组升级,再运行 `dsh-codex-connect doctor --json` 和兼容性检查。本契约不对未来版本作判断。
|
|
330
334
|
- 每日上游检查发现新的 DSH `latest` 或 `next` 候选版本时,会把 Codex Connect 安装到隔离 Profile 中,在没有 OAuth 凭据的情况下启动已安装的模型运行时,验证模型与推理强度发现,并确认提供方可被正确卸载。真实登录、额度和模型请求仍需在测试 Profile 中人工验证。
|
package/docs/design.i18n.yaml
CHANGED
|
@@ -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:
|
|
4
|
-
design.zh.md:
|
|
3
|
+
design.md: 6a633995a2ca0261f6c01f2b17710bf64dca87c7
|
|
4
|
+
design.zh.md: 6bf9359f089f52ef6b8e821f9a9aeab784e020bd
|
package/docs/design.md
CHANGED
|
@@ -10,7 +10,9 @@ The Host registers `llm-openai-codex` as the plugin-owned capability settings na
|
|
|
10
10
|
|
|
11
11
|
## OAuth persistence
|
|
12
12
|
|
|
13
|
-
The plugin uses `$DSH_HOME/.openai-codex-auth.json`, separate from Codex CLI/Desktop state.
|
|
13
|
+
The plugin uses `$DSH_HOME/.openai-codex-auth.json`, separate from Codex CLI/Desktop state. Format version 2 stores at most 16 OAuth accounts and names exactly one active account. Existing version-1 documents remain readable and migrate on the first credential mutation; that migration first creates the owner-only `.openai-codex-auth.json.v1-backup` rollback copy. A pre-existing rollback copy must be owner-only and match the current version-1 document or migration stops before replacing the main document. Removing any account or signing out deletes the rollback copy so removed credentials do not persist there. Documents are limited to 512 KiB. POSIX reads reject group/world-accessible files, non-regular files are rejected, writes are atomic, and mutations use the Harness cross-process file lock. Callers receive cloned credentials.
|
|
14
|
+
|
|
15
|
+
Browser account routes expose deterministic plugin-derived keys, local display labels, masked email addresses when present in the OAuth token, and active state. They never expose the provider's account id or token fields. Activation and deletion are serialized with browser OAuth. After OAuth resolution, quota, image-generation, and Auto-review requests resolve the account id stored with that exact access token, so a concurrent account switch cannot combine credentials from different accounts. Deleting the active account while another remains requires the caller to name the replacement; provider-global logout deletes every account. Browser-origin trust is a separate `$DSH_HOME/.openai-codex-trusted-origins.json` sidecar with `version: 1`, `mode: "allowlist"`, and exact normalized HTTP(S) origins; it never contains OAuth material and is changed only by the standalone CLI.
|
|
14
16
|
|
|
15
17
|
The settings routes and CLI reuse the existing OAuth path and route names for migration compatibility. Only an explicit login operation emits an authorization URL or code. Browser requests are accepted by default only from loopback; a remote request must use an exact effective HTTP(S) origin in the current sidecar, must not carry cross-site Fetch Metadata, and must match any supplied Origin exactly. The sidecar is re-read for every request, and unknown fields or modes fail closed. A login challenge accepts only credential-free HTTPS URLs and fails closed after 30 seconds or when the provider finishes without a URL; logout and disposal cancel pending waiters. Status responses are redacted. Doctor uses `lstat` metadata and never opens the document.
|
|
16
18
|
|
|
@@ -26,4 +28,4 @@ Before registration the plugin checks current provider ids. An existing `openai-
|
|
|
26
28
|
|
|
27
29
|
## Compatibility boundary
|
|
28
30
|
|
|
29
|
-
Alpha 4.
|
|
31
|
+
Alpha 4.26 pins Harness `0.1.2-rc.1` development dependencies and follows its pi-ai range `^0.84.2`. 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. The published compatibility record lists the exact Alpha 4.26 and DSH `0.1.2-rc.1` 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
|
@@ -10,7 +10,9 @@ Host 将 `llm-openai-codex` 注册为插件自有的能力 settings namespace。
|
|
|
10
10
|
|
|
11
11
|
## OAuth 持久化
|
|
12
12
|
|
|
13
|
-
插件使用 `$DSH_HOME/.openai-codex-auth.json`,与 Codex CLI/Desktop
|
|
13
|
+
插件使用 `$DSH_HOME/.openai-codex-auth.json`,与 Codex CLI/Desktop 状态分离。格式 version 2 最多保存 16 个 OAuth 账户,并明确指定唯一当前账户。原 version 1 文件仍可读取,第一次修改凭据时才迁移;迁移前会先生成仅所有者可读的 `.openai-codex-auth.json.v1-backup` 回退副本。若该副本已存在,它必须仅所有者可读且与当前 version 1 文件一致,否则迁移会在替换主文件前停止。移除任一账户或执行退出登录时会删除该副本,避免已移除凭据继续留存。文档大小上限为 512 KiB。POSIX 上拒绝组/其他用户可读文件,也拒绝非普通文件;写入采用原子替换,所有修改使用 Harness 跨进程文件锁,返回给调用方的是凭据副本。
|
|
14
|
+
|
|
15
|
+
浏览器账户路由只返回插件派生的稳定键、本地显示名称、OAuth token 中存在邮箱时的脱敏地址以及当前账户状态,不返回 provider 原始 account id 或 token 字段。账户切换和删除与浏览器 OAuth 串行执行;OAuth 解析完成后,额度、图片生成和 Auto-review 请求会查找与该 access token 精确配套的 account id,因此并发切换账户不会混用两个账户的凭据。仍有其他账户时,删除当前账户必须由调用方明确指定接替账户;provider 级退出登录会删除全部账户。浏览器 origin 授权单独存放于 `$DSH_HOME/.openai-codex-trusted-origins.json`,格式为 `version: 1`、`mode: "allowlist"` 和规范化的精确 HTTP(S) origin;其中不含 OAuth 内容,且只能通过独立 CLI 修改。
|
|
14
16
|
|
|
15
17
|
为兼容迁移,设置页路由、OAuth 路径和 provider id 不改名。浏览器请求默认只允许 loopback;远程请求必须使用当前 sidecar 中的精确有效 HTTP(S) origin,不能带 cross-site Fetch Metadata,若带 Origin 还必须精确匹配。每次请求都会重新读取 sidecar;未知字段或错误 mode 会快速失败。登录挑战只接受不含凭据的 HTTPS 地址;30 秒内未得到地址、provider 已结束但没有地址、退出登录或插件卸载时,所有 waiter 都会被清理。只有显式登录会输出授权 URL 或代码;状态输出会脱敏。doctor 只用 `lstat` 检查元数据,不打开文件。
|
|
16
18
|
|
|
@@ -22,4 +24,4 @@ Host 将 `llm-openai-codex` 注册为插件自有的能力 settings namespace。
|
|
|
22
24
|
|
|
23
25
|
注册前检查现有 provider id;发现 `openai-codex` 已被占用时,给出旧 bundle 或手动 provider 配置的定向迁移提示。boot-free CLI doctor 只报告包/运行时版本、OAuth 路径元数据、能力默认值和安全提示。
|
|
24
26
|
|
|
25
|
-
Alpha 4.
|
|
27
|
+
Alpha 4.26 固定使用 Harness `0.1.2-rc.1` 开发依赖,并跟随其 pi-ai 版本范围 `^0.84.2`。Node.js 支持范围仍为 `^22.19.0 || >=24.0.0`。keyed `settings.plugin.item` 集成保持不变,客户端类型继续从 Session Controller、Settings、Store 和 Renderer 的所属包导入。已发布兼容性记录列出 Alpha 4.26 与 DSH `0.1.2-rc.1` 的精确组合。资格、额度、模型、服务端上下文容量和后端协议仍由上游控制。测试仅使用临时 OAuth 文档和模拟网络响应,CI 不执行真实认证。
|
package/lib/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { At as logoutOpenAICodex,
|
|
2
|
+
import { At as logoutOpenAICodex, H as DSH_PLUGIN_API_PACKAGES, Lt as OPENAI_CODEX_PROVIDER, Mt as openAICodexModelCatalog, N as CODEX_CONNECT_VERSION, Rt as OpenAICodexCredentialStore, Tt as normalizeTrustedOrigin, X as readInstalledPackageVersion, Y as evaluateCompatibility, c as migrateOpenAICodexSearchHistory, d as OPENAI_CODEX_BASE_URL, gt as normalizeOpenAICodexProxyUrl, j as diagnoseOpenAICodex, jt as openAICodexAuthStatus, kt as loginOpenAICodex, l as CODEX_AUTO_REVIEW_MODEL, u as probeCodexAutoReview, wt as OpenAICodexTrustedOriginsStore, zt as openAICodexAuthPath } from "./src-FSN1b9Tk.js";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
import { Agent, ProxyAgent, fetch } from "undici";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
@@ -208,7 +208,7 @@ var CodexCapabilityDiagnostics = class {
|
|
|
208
208
|
packageVersions: versions
|
|
209
209
|
});
|
|
210
210
|
const missing = Object.values(versions).some((value) => value === null) || !/^v?\d+\.\d+\.\d+$/u.test(versions["node"] ?? "");
|
|
211
|
-
const runtime = DSH_PLUGIN_API_PACKAGES.some((name) => versions[name] !== null && versions[name] !== "0.1.2-
|
|
211
|
+
const runtime = DSH_PLUGIN_API_PACKAGES.some((name) => versions[name] !== null && versions[name] !== "0.1.2-rc.1") || compatibility.status === "incompatible" ? result("rejected", "declared-version-mismatch", "Use DSH API 0.1.2-rc.1 and pi-ai ^0.84.2 together. DSH 0.1.0-rc.7 requires Codex Connect 0.1.0-alpha.4.14.") : missing || compatibility.status === "unknown" ? result("unknown", "version-metadata-unavailable", "Run this command from the plugin installation in the intended profile.") : result("supported", "declared-host-versions-match", "Host package versions satisfy the declared requirements; this is not a live profile or browser compatibility test.");
|
|
212
212
|
const model = this.deps.catalog().find((item) => item.id === request.model)?.id ?? null;
|
|
213
213
|
const unknownNetwork = result("unknown", "not-probed", "Run capabilities --model <catalog-id> --probe explicitly; this sends a fixed short request and may consume quota.");
|
|
214
214
|
const checks = {
|
package/lib/client.js
CHANGED
|
@@ -5725,7 +5725,7 @@ window.__ModuleLoader__.load({
|
|
|
5725
5725
|
}
|
|
5726
5726
|
//#endregion
|
|
5727
5727
|
//#region src/version.ts
|
|
5728
|
-
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.
|
|
5728
|
+
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.26";
|
|
5729
5729
|
//#endregion
|
|
5730
5730
|
//#region src/client/OpenAICodexModelsCard.tsx
|
|
5731
5731
|
/** Compact Models account entry with quota disclosure and shared configuration. */
|
package/lib/index.d.ts
CHANGED
|
@@ -1,13 +1,29 @@
|
|
|
1
1
|
import z from "@deepseek-ai/schemastery";
|
|
2
|
-
import { AuthInteraction, Credential, CredentialInfo, CredentialStore } from "@earendil-works/pi-ai";
|
|
2
|
+
import { AuthInteraction, Credential, CredentialInfo, CredentialStore, OAuthCredential } from "@earendil-works/pi-ai";
|
|
3
3
|
import "@deepseek-ai/dsh-tools";
|
|
4
4
|
import { Context, Service } from "@deepseek-ai/cordis";
|
|
5
5
|
import { WebSearchProvider, WebSearchRequest, WebSearchResult } from "@deepseek-ai/dsh-web";
|
|
6
|
+
//#region src/account-profile.d.ts
|
|
7
|
+
type OpenAICodexAccountProfileSource = 'oauth' | 'generated';
|
|
8
|
+
//#endregion
|
|
6
9
|
//#region src/store.d.ts
|
|
7
10
|
/** Provider route and pi-ai provider id owned by this bundle. */
|
|
8
11
|
declare const OPENAI_CODEX_PROVIDER = "openai-codex";
|
|
9
12
|
/** Basename of the OAuth document inside the Harness home. */
|
|
10
13
|
declare const OPENAI_CODEX_AUTH_FILENAME = ".openai-codex-auth.json";
|
|
14
|
+
/** Maximum number of stored OpenAI Codex accounts. */
|
|
15
|
+
declare const OPENAI_CODEX_ACCOUNT_LIMIT = 16;
|
|
16
|
+
/** Maximum serialized credential document size. */
|
|
17
|
+
declare const OPENAI_CODEX_AUTH_DOCUMENT_LIMIT: number;
|
|
18
|
+
/** Suffix used for the one-time version-1 rollback copy. */
|
|
19
|
+
declare const OPENAI_CODEX_AUTH_V1_BACKUP_SUFFIX = ".v1-backup";
|
|
20
|
+
interface OpenAICodexAccountSummary {
|
|
21
|
+
accountKey: string;
|
|
22
|
+
displayName: string;
|
|
23
|
+
maskedEmail?: string;
|
|
24
|
+
profileSource: OpenAICodexAccountProfileSource;
|
|
25
|
+
active: boolean;
|
|
26
|
+
}
|
|
11
27
|
/**
|
|
12
28
|
* Resolve the default OAuth document path.
|
|
13
29
|
* @param dshHome - optional Harness-home override.
|
|
@@ -18,16 +34,28 @@ declare function openAICodexAuthPath(dshHome?: string): string;
|
|
|
18
34
|
declare class OpenAICodexCredentialStore implements CredentialStore {
|
|
19
35
|
/** Absolute credential document path. */
|
|
20
36
|
readonly filename: string;
|
|
37
|
+
/** Owner-only version-1 rollback copy, created at the first migration write. */
|
|
38
|
+
readonly version1BackupFilename: string;
|
|
21
39
|
/**
|
|
22
40
|
* @param filename - explicit document path, defaulting under `$DSH_HOME`.
|
|
23
41
|
*/
|
|
24
42
|
constructor(filename?: string);
|
|
25
43
|
/** Read and validate the current document without acquiring the writer lock. */
|
|
26
|
-
private
|
|
44
|
+
private readDocument;
|
|
45
|
+
private readDocumentAt;
|
|
46
|
+
private writeDocument;
|
|
27
47
|
/** @inheritdoc */
|
|
28
48
|
read(providerId: string): Promise<Credential | undefined>;
|
|
29
49
|
/** @inheritdoc */
|
|
30
50
|
list(): Promise<readonly CredentialInfo[]>;
|
|
51
|
+
/** List browser-safe account summaries without exposing provider account ids. */
|
|
52
|
+
accounts(): Promise<readonly OpenAICodexAccountSummary[]>;
|
|
53
|
+
/** Resolve the account id stored with one exact access token. */
|
|
54
|
+
accountIdForAccess(access: string): Promise<string | undefined>;
|
|
55
|
+
/** Select a stored account using its browser-safe key. */
|
|
56
|
+
activate(selectedAccountKey: string): Promise<OAuthCredential>;
|
|
57
|
+
/** Remove one account; active removal requires an explicit stored replacement. */
|
|
58
|
+
removeAccount(selectedAccountKey: string, replacementAccountKey?: string): Promise<void>;
|
|
31
59
|
/** @inheritdoc */
|
|
32
60
|
modify(providerId: string, fn: (current: Credential | undefined) => Promise<Credential | undefined>): Promise<Credential | undefined>;
|
|
33
61
|
/** @inheritdoc */
|
|
@@ -180,7 +208,7 @@ declare const IMAGE_GENERATE_TOOL_NAME = "codex_connect_image_generate";
|
|
|
180
208
|
//#region src/compatibility.d.ts
|
|
181
209
|
declare const COMPATIBILITY_SCHEMA_VERSION: 1;
|
|
182
210
|
declare const SUPPORTED_NODE_RANGE = "^22.19.0 || >=24.0.0";
|
|
183
|
-
declare const SUPPORTED_DSH_PLUGIN_API_VERSION = "0.1.2-
|
|
211
|
+
declare const SUPPORTED_DSH_PLUGIN_API_VERSION = "0.1.2-rc.1";
|
|
184
212
|
declare const SUPPORTED_PI_AI_RANGE = "^0.84.2";
|
|
185
213
|
declare const PI_AI_PACKAGE = "@earendil-works/pi-ai";
|
|
186
214
|
declare const DSH_PLUGIN_API_PACKAGES: readonly ["@deepseek-ai/dsh-agent", "@deepseek-ai/dsh-atomic-write", "@deepseek-ai/dsh-attachment", "@deepseek-ai/dsh-home-paths", "@deepseek-ai/dsh-host-webserver", "@deepseek-ai/dsh-invariants", "@deepseek-ai/dsh-llm", "@deepseek-ai/dsh-llm-pi-ai", "@deepseek-ai/dsh-fs", "@deepseek-ai/dsh-session", "@deepseek-ai/dsh-settings", "@deepseek-ai/dsh-tools", "@deepseek-ai/dsh-util-values", "@deepseek-ai/dsh-web"];
|
|
@@ -224,7 +252,7 @@ declare const COMPATIBILITY_CONTRACT: {
|
|
|
224
252
|
readonly node: "^22.19.0 || >=24.0.0";
|
|
225
253
|
};
|
|
226
254
|
readonly dshPluginApi: {
|
|
227
|
-
readonly version: "0.1.2-
|
|
255
|
+
readonly version: "0.1.2-rc.1";
|
|
228
256
|
readonly packages: readonly ["@deepseek-ai/dsh-agent", "@deepseek-ai/dsh-atomic-write", "@deepseek-ai/dsh-attachment", "@deepseek-ai/dsh-home-paths", "@deepseek-ai/dsh-host-webserver", "@deepseek-ai/dsh-invariants", "@deepseek-ai/dsh-llm", "@deepseek-ai/dsh-llm-pi-ai", "@deepseek-ai/dsh-fs", "@deepseek-ai/dsh-session", "@deepseek-ai/dsh-settings", "@deepseek-ai/dsh-tools", "@deepseek-ai/dsh-util-values", "@deepseek-ai/dsh-web"];
|
|
229
257
|
};
|
|
230
258
|
readonly piAi: {
|
|
@@ -731,4 +759,4 @@ declare const Config: z<Config>;
|
|
|
731
759
|
*/
|
|
732
760
|
declare function apply(ctx: Context, config: Config): void;
|
|
733
761
|
//#endregion
|
|
734
|
-
export { COMPATIBILITY_CONTRACT, COMPATIBILITY_PACKAGES, COMPATIBILITY_SCHEMA_VERSION, type CompatibilityDetectionOptions, type CompatibilityEntry, type CompatibilityEvaluationInput, type CompatibilityPackageName, type CompatibilityReport, type CompatibilityStatus, 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, type GeneratedImagePayload, IMAGE_GENERATE_TOOL_NAME, type ImageGenerationRequest, type ImageGenerationResponse, type ImageRequestContext, 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, type OpenAICodexAuthStatus, OpenAICodexCredentialStore, type OpenAICodexCredits, type OpenAICodexDiagnosticOptions, type OpenAICodexDiagnosticReport, type OpenAICodexHistoryMigrationFile, type OpenAICodexHistoryMigrationOptions, type OpenAICodexHistoryMigrationResult, type OpenAICodexIndividualLimit, OpenAICodexProxyManager, type OpenAICodexProxyProbeClassification, type OpenAICodexProxyProbeResult, type OpenAICodexRateLimit, type OpenAICodexRateLimitWindow, type OpenAICodexSearchContextSize, type OpenAICodexSearchMode, OpenAICodexSearchProvider, type OpenAICodexSearchProviderOptions, type OpenAICodexSearchRequestRecord, type OpenAICodexSettingsConfig, OpenAICodexTransport, OpenAICodexTransportError, type OpenAICodexTransportErrorCode, type OpenAICodexTransportV1, type OpenAICodexUpdateResult, type OpenAICodexUsage, 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 };
|
|
762
|
+
export { COMPATIBILITY_CONTRACT, COMPATIBILITY_PACKAGES, COMPATIBILITY_SCHEMA_VERSION, type CompatibilityDetectionOptions, type CompatibilityEntry, type CompatibilityEvaluationInput, type CompatibilityPackageName, type CompatibilityReport, type CompatibilityStatus, 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, type GeneratedImagePayload, IMAGE_GENERATE_TOOL_NAME, type ImageGenerationRequest, type ImageGenerationResponse, type ImageRequestContext, OPENAI_CODEX_ACCOUNT_LIMIT, OPENAI_CODEX_AUTH_DOCUMENT_LIMIT, OPENAI_CODEX_AUTH_FILENAME, OPENAI_CODEX_AUTH_V1_BACKUP_SUFFIX, 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, type OpenAICodexAccountSummary, type OpenAICodexAuthStatus, OpenAICodexCredentialStore, type OpenAICodexCredits, type OpenAICodexDiagnosticOptions, type OpenAICodexDiagnosticReport, type OpenAICodexHistoryMigrationFile, type OpenAICodexHistoryMigrationOptions, type OpenAICodexHistoryMigrationResult, type OpenAICodexIndividualLimit, OpenAICodexProxyManager, type OpenAICodexProxyProbeClassification, type OpenAICodexProxyProbeResult, type OpenAICodexRateLimit, type OpenAICodexRateLimitWindow, type OpenAICodexSearchContextSize, type OpenAICodexSearchMode, OpenAICodexSearchProvider, type OpenAICodexSearchProviderOptions, type OpenAICodexSearchRequestRecord, type OpenAICodexSettingsConfig, OpenAICodexTransport, OpenAICodexTransportError, type OpenAICodexTransportErrorCode, type OpenAICodexTransportV1, type OpenAICodexUpdateResult, type OpenAICodexUsage, 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 };
|
package/lib/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as OPENAI_CODEX_LOCAL_PROXY_CANDIDATES, A as assertNoOpenAICodexProviderConflict, At as logoutOpenAICodex, B as COMPATIBILITY_PACKAGES, C as OPENAI_CODEX_TRANSPORT_ERROR_CODES, Ct as isFastModeSessionId, D as isOpenAICodexTransportError, Dt as parseOpenAICodexUsage, E as OpenAICodexTransportError, Et as OPENAI_CODEX_USAGE_URL, F as checkForOpenAICodexUpdate, Ft as
|
|
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 };
|
|
1
|
+
import { $ as OPENAI_CODEX_LOCAL_PROXY_CANDIDATES, A as assertNoOpenAICodexProviderConflict, At as logoutOpenAICodex, B as COMPATIBILITY_PACKAGES, C as OPENAI_CODEX_TRANSPORT_ERROR_CODES, Ct as isFastModeSessionId, D as isOpenAICodexTransportError, Dt as parseOpenAICodexUsage, E as OpenAICodexTransportError, Et as OPENAI_CODEX_USAGE_URL, F as checkForOpenAICodexUpdate, Ft as OPENAI_CODEX_AUTH_FILENAME, G as SUPPORTED_NODE_RANGE, H as DSH_PLUGIN_API_PACKAGES, I as compareOpenAICodexVersions, It as OPENAI_CODEX_AUTH_V1_BACKUP_SUFFIX, J as detectCompatibility, K as SUPPORTED_PI_AI_RANGE, L as parseOpenAICodexUpdateResult, Lt as OPENAI_CODEX_PROVIDER, M as openAICodexConflictMessage, Nt as OPENAI_CODEX_ACCOUNT_LIMIT, O as VIEW_IMAGE_TOOL_NAME, Ot as readOpenAICodexRateLimits, P as OPENAI_CODEX_UPDATE_PATH, Pt as OPENAI_CODEX_AUTH_DOCUMENT_LIMIT, Q as OPENAI_CODEX_PROXY_TEST_PATH, R as parseOpenAICodexVersion, Rt as OpenAICodexCredentialStore, S as OPENAI_CODEX_TRANSPORT_API_VERSION, St as OPENAI_CODEX_FAST_MODE_MAX_SESSION_ID_LENGTH, T as OpenAICodexTransport, U as PI_AI_PACKAGE, V as COMPATIBILITY_SCHEMA_VERSION, W as SUPPORTED_DSH_PLUGIN_API_VERSION, Y as evaluateCompatibility, Z as OPENAI_CODEX_PROXY_DETECT_PATH, _ as OPENAI_CODEX_IMAGE_MAX_COUNT, _t as resolveOpenAICodexProxyUrl, a as name, at as listOpenAICodexProxyCandidates, b as OPENAI_CODEX_IMAGE_PROMPT_MAX_LENGTH, bt as FastModeRegistry, c as migrateOpenAICodexSearchHistory, ct as DEFAULT_OPENAI_CODEX_SEARCH_MAX_OUTPUT_TOKENS, d as OPENAI_CODEX_BASE_URL, dt as DEFAULT_OPENAI_CODEX_SETTINGS, et as OPENAI_CODEX_PROXY_CANDIDATE_LIMIT, f as OPENAI_CODEX_SEARCH_PROVIDER, ft as OPENAI_CODEX_SETTINGS_NAMESPACE, g as OPENAI_CODEX_IMAGE_GENERATION_URL, h as mapOpenAICodexSearchResponse, ht as isValidOpenAICodexProxyUrl, i as inject, it as detectOpenAICodexProxies, j as diagnoseOpenAICodex, jt as openAICodexAuthStatus, k as IMAGE_GENERATE_TOOL_NAME, kt as loginOpenAICodex, lt as DEFAULT_OPENAI_CODEX_SEARCH_MODE, m as OpenAICodexSearchProvider, mt as isValidOpenAICodexContextWindowOverrides, n as OPENAI_CODEX_SETTINGS_NS, nt as OPENAI_CODEX_PROXY_PROBE_URL, o as OPENAI_CODEX_HISTORY_BACKUP_SUFFIX, ot as DEFAULT_OPENAI_CODEX_PROXY_URL, p as OPENAI_CODEX_SEARCH_URL, pt as decodeOpenAICodexSettings, q as assessCompatibility, r as apply, rt as OpenAICodexProxyManager, s as OPENAI_CODEX_SEARCH_MODEL_REQUEST_EVENT, st as DEFAULT_OPENAI_CODEX_SEARCH_CONTEXT_SIZE, t as Config, tt as OPENAI_CODEX_PROXY_PROBE_TIMEOUT_MS, ut as DEFAULT_OPENAI_CODEX_SEARCH_MODEL, v as OPENAI_CODEX_IMAGE_MAX_ERROR_BYTES, vt as resolveOpenAICodexSettings, w as OPENAI_CODEX_TRANSPORT_SERVICE, x as OPENAI_CODEX_IMAGE_REQUEST_TIMEOUT_MS, xt as OPENAI_CODEX_FAST_MODE_MAX_SESSIONS, y as OPENAI_CODEX_IMAGE_MAX_RESPONSE_BYTES, yt as OPENAI_CODEX_FAST_MODE_PATH, z as COMPATIBILITY_CONTRACT, zt as openAICodexAuthPath } from "./src-FSN1b9Tk.js";
|
|
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_ACCOUNT_LIMIT, OPENAI_CODEX_AUTH_DOCUMENT_LIMIT, OPENAI_CODEX_AUTH_FILENAME, OPENAI_CODEX_AUTH_V1_BACKUP_SUFFIX, 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 };
|
|
@@ -9,6 +9,7 @@ import { PiAiAdapter } from "@deepseek-ai/dsh-llm-pi-ai";
|
|
|
9
9
|
import { link, lstat, mkdir, open, readFile, readdir, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
10
10
|
import { withFileLock, writeFileAtomic } from "@deepseek-ai/dsh-atomic-write";
|
|
11
11
|
import { resolveDshHome } from "@deepseek-ai/dsh-home-paths";
|
|
12
|
+
import { Buffer as Buffer$1 } from "node:buffer";
|
|
12
13
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
13
14
|
import { Agent, Dispatcher, ProxyAgent, fetch as fetch$1, getGlobalDispatcher, setGlobalDispatcher } from "undici";
|
|
14
15
|
import { fileURLToPath } from "node:url";
|
|
@@ -23,6 +24,55 @@ import { Service } from "@deepseek-ai/cordis";
|
|
|
23
24
|
import { constants } from "node:fs";
|
|
24
25
|
import { WebError } from "@deepseek-ai/dsh-web";
|
|
25
26
|
import { constants as constants$1, zstdCompressSync, zstdDecompressSync } from "node:zlib";
|
|
27
|
+
//#region src/account-profile.ts
|
|
28
|
+
/** Safe browser labels derived locally from OpenAI Codex OAuth credentials. */
|
|
29
|
+
const PROFILE_CLAIM = "https://api.openai.com/profile";
|
|
30
|
+
const MAX_JWT_PAYLOAD_LENGTH = 65536;
|
|
31
|
+
const MAX_LABEL_LENGTH = 128;
|
|
32
|
+
const MAX_EMAIL_LENGTH = 320;
|
|
33
|
+
function boundedText$1(value, maximum) {
|
|
34
|
+
if (typeof value !== "string") return void 0;
|
|
35
|
+
const normalized = value.replace(/[\u0000-\u001f\u007f]/gu, "").trim();
|
|
36
|
+
return normalized.length > 0 && normalized.length <= maximum ? normalized : void 0;
|
|
37
|
+
}
|
|
38
|
+
function maskEmail(email) {
|
|
39
|
+
const separator = email.lastIndexOf("@");
|
|
40
|
+
if (separator <= 0 || separator === email.length - 1) return "••••";
|
|
41
|
+
const local = email.slice(0, separator);
|
|
42
|
+
const domain = email.slice(separator + 1);
|
|
43
|
+
return `${local.slice(0, Math.min(2, local.length))}••@${domain}`;
|
|
44
|
+
}
|
|
45
|
+
function decodeOauthProfile(access) {
|
|
46
|
+
const payload = access.split(".")[1];
|
|
47
|
+
if (payload === void 0 || payload.length === 0 || payload.length > MAX_JWT_PAYLOAD_LENGTH) return {};
|
|
48
|
+
try {
|
|
49
|
+
const decoded = JSON.parse(Buffer$1.from(payload, "base64url").toString("utf8"));
|
|
50
|
+
if (typeof decoded !== "object" || decoded === null || Array.isArray(decoded)) return {};
|
|
51
|
+
const profile = decoded[PROFILE_CLAIM];
|
|
52
|
+
if (typeof profile !== "object" || profile === null || Array.isArray(profile)) return {};
|
|
53
|
+
const record = profile;
|
|
54
|
+
const name = boundedText$1(record["name"], MAX_LABEL_LENGTH);
|
|
55
|
+
const email = boundedText$1(record["email"], MAX_EMAIL_LENGTH);
|
|
56
|
+
return {
|
|
57
|
+
...name === void 0 ? {} : { name },
|
|
58
|
+
...email === void 0 ? {} : { email }
|
|
59
|
+
};
|
|
60
|
+
} catch {
|
|
61
|
+
return {};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** Resolve display-only labels without network access or provider account identifiers. */
|
|
65
|
+
function resolveOpenAICodexAccountProfiles(credentials) {
|
|
66
|
+
return credentials.map((credential, index) => {
|
|
67
|
+
const oauth = decodeOauthProfile(credential.access);
|
|
68
|
+
return {
|
|
69
|
+
displayName: oauth.name ?? `ChatGPT account ${String(index + 1)}`,
|
|
70
|
+
...oauth.email === void 0 ? {} : { maskedEmail: maskEmail(oauth.email) },
|
|
71
|
+
source: oauth.name === void 0 && oauth.email === void 0 ? "generated" : "oauth"
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
26
76
|
//#region src/store.ts
|
|
27
77
|
/**
|
|
28
78
|
* Owner-only persistent OAuth credential storage for the OpenAI Codex bundle.
|
|
@@ -32,40 +82,28 @@ import { constants as constants$1, zstdCompressSync, zstdDecompressSync } from "
|
|
|
32
82
|
const OPENAI_CODEX_PROVIDER = "openai-codex";
|
|
33
83
|
/** Basename of the OAuth document inside the Harness home. */
|
|
34
84
|
const OPENAI_CODEX_AUTH_FILENAME = ".openai-codex-auth.json";
|
|
35
|
-
/** Current on-disk format
|
|
36
|
-
const AUTH_FORMAT_VERSION =
|
|
85
|
+
/** Current multi-account on-disk format. */
|
|
86
|
+
const AUTH_FORMAT_VERSION = 2;
|
|
87
|
+
/** Maximum number of stored OpenAI Codex accounts. */
|
|
88
|
+
const OPENAI_CODEX_ACCOUNT_LIMIT = 16;
|
|
89
|
+
/** Maximum serialized credential document size. */
|
|
90
|
+
const OPENAI_CODEX_AUTH_DOCUMENT_LIMIT = 524288;
|
|
91
|
+
/** Suffix used for the one-time version-1 rollback copy. */
|
|
92
|
+
const OPENAI_CODEX_AUTH_V1_BACKUP_SUFFIX = ".v1-backup";
|
|
37
93
|
/** Whether a filesystem error reports an absent path. */
|
|
38
94
|
function isENOENT$1(error) {
|
|
39
95
|
return error?.code === "ENOENT";
|
|
40
96
|
}
|
|
41
97
|
/** Reject a credential document readable by another POSIX user. */
|
|
42
|
-
|
|
43
|
-
let mode;
|
|
44
|
-
try {
|
|
45
|
-
mode = (await stat(filename)).mode;
|
|
46
|
-
} catch (error) {
|
|
47
|
-
if (isENOENT$1(error)) return;
|
|
48
|
-
throw error;
|
|
49
|
-
}
|
|
98
|
+
function assertOwnerOnly$1(filename, mode) {
|
|
50
99
|
/* v8 ignore next -- native Windows coverage takes the mode-less branch */
|
|
51
100
|
if (process.platform === "win32") return;
|
|
52
101
|
/* v8 ignore start -- POSIX tests cover this branch; Windows cannot express it */
|
|
53
102
|
if ((mode & 63) !== 0) throw new Error(`openai-codex: ${filename} is readable beyond its owner (mode ${(mode & 511).toString(8)}); run "chmod 600 ${filename}" before starting again`);
|
|
54
103
|
/* v8 ignore stop */
|
|
55
104
|
}
|
|
56
|
-
/** Validate
|
|
57
|
-
function
|
|
58
|
-
let value;
|
|
59
|
-
try {
|
|
60
|
-
value = JSON.parse(text);
|
|
61
|
-
} catch {
|
|
62
|
-
throw new Error(`openai-codex: ${filename} is not valid JSON`);
|
|
63
|
-
}
|
|
64
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`openai-codex: ${filename} must contain an object`);
|
|
65
|
-
const document = value;
|
|
66
|
-
if (document["version"] !== AUTH_FORMAT_VERSION) throw new Error(`openai-codex: ${filename} has unsupported auth format version ${String(document["version"])}`);
|
|
67
|
-
if (Object.keys(document).some((key) => key !== "version" && key !== "credential")) throw new Error(`openai-codex: ${filename} contains an unknown top-level field`);
|
|
68
|
-
const raw = document["credential"];
|
|
105
|
+
/** Validate one OAuth credential without quoting token-bearing input. */
|
|
106
|
+
function parseCredential(raw, filename) {
|
|
69
107
|
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) throw new Error(`openai-codex: ${filename} credential must be an object`);
|
|
70
108
|
const credential = raw;
|
|
71
109
|
if (Object.keys(credential).some((key) => ![
|
|
@@ -82,15 +120,65 @@ function parseDocument$2(text, filename) {
|
|
|
82
120
|
"accountId"
|
|
83
121
|
]) if (typeof credential[key] !== "string" || credential[key].length === 0) throw new Error(`openai-codex: ${filename} credential ${key} must be a non-empty string`);
|
|
84
122
|
if (typeof credential["expires"] !== "number" || !Number.isFinite(credential["expires"]) || credential["expires"] <= 0) throw new Error(`openai-codex: ${filename} credential expires must be a positive finite number`);
|
|
123
|
+
return credential;
|
|
124
|
+
}
|
|
125
|
+
/** Validate the strict JSON document without quoting token-bearing input. */
|
|
126
|
+
function parseDocument$2(text, filename) {
|
|
127
|
+
let value;
|
|
128
|
+
try {
|
|
129
|
+
value = JSON.parse(text);
|
|
130
|
+
} catch {
|
|
131
|
+
throw new Error(`openai-codex: ${filename} is not valid JSON`);
|
|
132
|
+
}
|
|
133
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`openai-codex: ${filename} must contain an object`);
|
|
134
|
+
const document = value;
|
|
135
|
+
if (document["version"] === 1) {
|
|
136
|
+
if (Object.keys(document).some((key) => key !== "version" && key !== "credential")) throw new Error(`openai-codex: ${filename} contains an unknown top-level field`);
|
|
137
|
+
return {
|
|
138
|
+
version: 1,
|
|
139
|
+
credential: parseCredential(document["credential"], filename)
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
if (document["version"] !== AUTH_FORMAT_VERSION) throw new Error(`openai-codex: ${filename} has unsupported auth format version ${String(document["version"])}`);
|
|
143
|
+
if (Object.keys(document).some((key) => ![
|
|
144
|
+
"version",
|
|
145
|
+
"activeAccountId",
|
|
146
|
+
"credentials"
|
|
147
|
+
].includes(key))) throw new Error(`openai-codex: ${filename} contains an unknown top-level field`);
|
|
148
|
+
if (typeof document["activeAccountId"] !== "string" || document["activeAccountId"].length === 0) throw new Error(`openai-codex: ${filename} activeAccountId must be a non-empty string`);
|
|
149
|
+
if (!Array.isArray(document["credentials"]) || document["credentials"].length === 0) throw new Error(`openai-codex: ${filename} credentials must be a non-empty array`);
|
|
150
|
+
if (document["credentials"].length > 16) throw new Error(`openai-codex: ${filename} exceeds the ${String(16)} account limit`);
|
|
151
|
+
const credentials = document["credentials"].map((raw) => parseCredential(raw, filename));
|
|
152
|
+
const accountIds = new Set(credentials.map((credential) => credential.accountId));
|
|
153
|
+
if (accountIds.size !== credentials.length) throw new Error(`openai-codex: ${filename} contains duplicate accountId values`);
|
|
154
|
+
if (!accountIds.has(document["activeAccountId"])) throw new Error(`openai-codex: ${filename} activeAccountId does not identify a stored credential`);
|
|
85
155
|
return {
|
|
86
156
|
version: AUTH_FORMAT_VERSION,
|
|
87
|
-
|
|
157
|
+
activeAccountId: document["activeAccountId"],
|
|
158
|
+
credentials
|
|
88
159
|
};
|
|
89
160
|
}
|
|
90
161
|
/** Detach a credential from callers that may mutate provider-owned extras. */
|
|
91
162
|
function cloneCredential(credential) {
|
|
92
163
|
return structuredClone(credential);
|
|
93
164
|
}
|
|
165
|
+
function documentCredentials(document) {
|
|
166
|
+
return document.version === 1 ? [document.credential] : document.credentials;
|
|
167
|
+
}
|
|
168
|
+
function activeCredential(document) {
|
|
169
|
+
if (document.version === 1) return document.credential;
|
|
170
|
+
const active = document.credentials.find((credential) => credential.accountId === document.activeAccountId);
|
|
171
|
+
if (active === void 0) throw new Error("openai-codex: active credential invariant failed");
|
|
172
|
+
return active;
|
|
173
|
+
}
|
|
174
|
+
function accountKey$1(accountId) {
|
|
175
|
+
return `acct_${createHash("sha256").update(accountId).digest("base64url")}`;
|
|
176
|
+
}
|
|
177
|
+
function serializeDocument(document) {
|
|
178
|
+
const text = `${JSON.stringify(document, null, 2)}\n`;
|
|
179
|
+
if (Buffer.byteLength(text) > 524288) throw new Error(`openai-codex: credential document exceeds ${String(OPENAI_CODEX_AUTH_DOCUMENT_LIMIT)} bytes`);
|
|
180
|
+
return text;
|
|
181
|
+
}
|
|
94
182
|
/**
|
|
95
183
|
* Resolve the default OAuth document path.
|
|
96
184
|
* @param dshHome - optional Harness-home override.
|
|
@@ -103,35 +191,140 @@ function openAICodexAuthPath(dshHome) {
|
|
|
103
191
|
var OpenAICodexCredentialStore = class {
|
|
104
192
|
/** Absolute credential document path. */
|
|
105
193
|
filename;
|
|
194
|
+
/** Owner-only version-1 rollback copy, created at the first migration write. */
|
|
195
|
+
version1BackupFilename;
|
|
106
196
|
/**
|
|
107
197
|
* @param filename - explicit document path, defaulting under `$DSH_HOME`.
|
|
108
198
|
*/
|
|
109
199
|
constructor(filename = openAICodexAuthPath()) {
|
|
110
200
|
this.filename = resolve(filename);
|
|
201
|
+
this.version1BackupFilename = join(dirname(this.filename), `${basename(this.filename)}${OPENAI_CODEX_AUTH_V1_BACKUP_SUFFIX}`);
|
|
111
202
|
}
|
|
112
203
|
/** Read and validate the current document without acquiring the writer lock. */
|
|
113
|
-
async
|
|
114
|
-
|
|
115
|
-
|
|
204
|
+
async readDocument() {
|
|
205
|
+
return this.readDocumentAt(this.filename);
|
|
206
|
+
}
|
|
207
|
+
async readDocumentAt(filename) {
|
|
208
|
+
let handle;
|
|
116
209
|
try {
|
|
117
|
-
|
|
210
|
+
handle = await open(filename, "r");
|
|
118
211
|
} catch (error) {
|
|
119
212
|
if (isENOENT$1(error)) return void 0;
|
|
120
213
|
throw error;
|
|
121
214
|
}
|
|
122
|
-
|
|
215
|
+
try {
|
|
216
|
+
const info = await handle.stat();
|
|
217
|
+
if (!info.isFile()) throw new Error(`openai-codex: ${filename} must be a regular file`);
|
|
218
|
+
assertOwnerOnly$1(filename, info.mode);
|
|
219
|
+
if (info.size > 524288) throw new Error(`openai-codex: ${filename} exceeds ${String(OPENAI_CODEX_AUTH_DOCUMENT_LIMIT)} bytes`);
|
|
220
|
+
return parseDocument$2(await handle.readFile("utf8"), filename);
|
|
221
|
+
} finally {
|
|
222
|
+
await handle.close();
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
async writeDocument(document, previous) {
|
|
226
|
+
const text = serializeDocument(document);
|
|
227
|
+
if (previous?.version === 1) {
|
|
228
|
+
const existingBackup = await this.readDocumentAt(this.version1BackupFilename);
|
|
229
|
+
if (existingBackup === void 0) await writeFileAtomic(this.version1BackupFilename, serializeDocument(previous), {
|
|
230
|
+
mode: 384,
|
|
231
|
+
dirMode: 448
|
|
232
|
+
});
|
|
233
|
+
else if (existingBackup.version !== 1 || serializeDocument(existingBackup) !== serializeDocument(previous)) throw new Error(`openai-codex: ${this.version1BackupFilename} rollback copy does not match the current version 1 credential`);
|
|
234
|
+
}
|
|
235
|
+
await writeFileAtomic(this.filename, text, {
|
|
236
|
+
mode: 384,
|
|
237
|
+
dirMode: 448
|
|
238
|
+
});
|
|
123
239
|
}
|
|
124
240
|
/** @inheritdoc */
|
|
125
241
|
async read(providerId) {
|
|
126
|
-
|
|
242
|
+
if (providerId !== "openai-codex") return void 0;
|
|
243
|
+
const document = await this.readDocument();
|
|
244
|
+
return document === void 0 ? void 0 : cloneCredential(activeCredential(document));
|
|
127
245
|
}
|
|
128
246
|
/** @inheritdoc */
|
|
129
247
|
async list() {
|
|
130
|
-
return await this.
|
|
248
|
+
return await this.readDocument() === void 0 ? [] : [{
|
|
131
249
|
providerId: OPENAI_CODEX_PROVIDER,
|
|
132
250
|
type: "oauth"
|
|
133
251
|
}];
|
|
134
252
|
}
|
|
253
|
+
/** List browser-safe account summaries without exposing provider account ids. */
|
|
254
|
+
async accounts() {
|
|
255
|
+
const document = await this.readDocument();
|
|
256
|
+
if (document === void 0) return [];
|
|
257
|
+
const credentials = documentCredentials(document);
|
|
258
|
+
const profiles = resolveOpenAICodexAccountProfiles(credentials);
|
|
259
|
+
const activeAccountId = activeCredential(document).accountId;
|
|
260
|
+
return credentials.map((credential, index) => ({
|
|
261
|
+
accountKey: accountKey$1(credential.accountId),
|
|
262
|
+
displayName: profiles[index].displayName,
|
|
263
|
+
...profiles[index].maskedEmail === void 0 ? {} : { maskedEmail: profiles[index].maskedEmail },
|
|
264
|
+
profileSource: profiles[index].source,
|
|
265
|
+
active: credential.accountId === activeAccountId
|
|
266
|
+
}));
|
|
267
|
+
}
|
|
268
|
+
/** Resolve the account id stored with one exact access token. */
|
|
269
|
+
async accountIdForAccess(access) {
|
|
270
|
+
const document = await this.readDocument();
|
|
271
|
+
if (document === void 0) return void 0;
|
|
272
|
+
return documentCredentials(document).find((credential) => credential.access === access)?.accountId;
|
|
273
|
+
}
|
|
274
|
+
/** Select a stored account using its browser-safe key. */
|
|
275
|
+
async activate(selectedAccountKey) {
|
|
276
|
+
await mkdir(dirname(this.filename), {
|
|
277
|
+
recursive: true,
|
|
278
|
+
mode: 448
|
|
279
|
+
});
|
|
280
|
+
return withFileLock(this.filename, async () => {
|
|
281
|
+
const document = await this.readDocument();
|
|
282
|
+
if (document === void 0) throw new Error("openai-codex: account not found");
|
|
283
|
+
const credentials = documentCredentials(document);
|
|
284
|
+
const selected = credentials.find((credential) => accountKey$1(credential.accountId) === selectedAccountKey);
|
|
285
|
+
if (selected === void 0) throw new Error("openai-codex: account not found");
|
|
286
|
+
await this.writeDocument({
|
|
287
|
+
version: AUTH_FORMAT_VERSION,
|
|
288
|
+
activeAccountId: selected.accountId,
|
|
289
|
+
credentials: credentials.map(cloneCredential)
|
|
290
|
+
}, document);
|
|
291
|
+
return cloneCredential(selected);
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
/** Remove one account; active removal requires an explicit stored replacement. */
|
|
295
|
+
async removeAccount(selectedAccountKey, replacementAccountKey) {
|
|
296
|
+
await mkdir(dirname(this.filename), {
|
|
297
|
+
recursive: true,
|
|
298
|
+
mode: 448
|
|
299
|
+
});
|
|
300
|
+
await withFileLock(this.filename, async () => {
|
|
301
|
+
const document = await this.readDocument();
|
|
302
|
+
if (document === void 0) throw new Error("openai-codex: account not found");
|
|
303
|
+
const credentials = [...documentCredentials(document)];
|
|
304
|
+
const removeIndex = credentials.findIndex((credential) => accountKey$1(credential.accountId) === selectedAccountKey);
|
|
305
|
+
if (removeIndex < 0) throw new Error("openai-codex: account not found");
|
|
306
|
+
const removed = credentials[removeIndex];
|
|
307
|
+
const active = activeCredential(document);
|
|
308
|
+
const remaining = credentials.filter((_, index) => index !== removeIndex);
|
|
309
|
+
let nextActive = active.accountId;
|
|
310
|
+
if (removed.accountId === active.accountId && remaining.length > 0) {
|
|
311
|
+
if (replacementAccountKey === void 0) throw new Error("openai-codex: removing the active account requires replacementAccountKey");
|
|
312
|
+
const replacement = remaining.find((credential) => accountKey$1(credential.accountId) === replacementAccountKey);
|
|
313
|
+
if (replacement === void 0) throw new Error("openai-codex: replacement account not found");
|
|
314
|
+
nextActive = replacement.accountId;
|
|
315
|
+
} else if (replacementAccountKey !== void 0) throw new Error("openai-codex: replacementAccountKey is only valid when removing the active account");
|
|
316
|
+
await rm(this.version1BackupFilename, { force: true });
|
|
317
|
+
if (remaining.length === 0) {
|
|
318
|
+
await rm(this.filename, { force: true });
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
await this.writeDocument({
|
|
322
|
+
version: AUTH_FORMAT_VERSION,
|
|
323
|
+
activeAccountId: nextActive,
|
|
324
|
+
credentials: remaining.map(cloneCredential)
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
}
|
|
135
328
|
/** @inheritdoc */
|
|
136
329
|
async modify(providerId, fn) {
|
|
137
330
|
if (providerId !== "openai-codex") throw new Error(`openai-codex: credential store does not own provider "${providerId}"`);
|
|
@@ -140,18 +333,22 @@ var OpenAICodexCredentialStore = class {
|
|
|
140
333
|
mode: 448
|
|
141
334
|
});
|
|
142
335
|
return withFileLock(this.filename, async () => {
|
|
143
|
-
const
|
|
336
|
+
const currentDocument = await this.readDocument();
|
|
337
|
+
const current = currentDocument === void 0 ? void 0 : cloneCredential(activeCredential(currentDocument));
|
|
144
338
|
const candidate = await fn(current);
|
|
145
339
|
if (candidate === void 0) return current;
|
|
146
|
-
const
|
|
340
|
+
const validated = parseCredential(candidate, this.filename);
|
|
341
|
+
const credentials = currentDocument === void 0 ? [] : [...documentCredentials(currentDocument)];
|
|
342
|
+
const existingIndex = credentials.findIndex((credential) => credential.accountId === validated.accountId);
|
|
343
|
+
if (existingIndex >= 0) credentials[existingIndex] = validated;
|
|
344
|
+
else credentials.push(validated);
|
|
345
|
+
if (credentials.length > 16) throw new Error(`openai-codex: credential store accepts at most ${String(16)} accounts`);
|
|
346
|
+
await this.writeDocument({
|
|
147
347
|
version: AUTH_FORMAT_VERSION,
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
dirMode: 448
|
|
153
|
-
});
|
|
154
|
-
return cloneCredential(document.credential);
|
|
348
|
+
activeAccountId: validated.accountId,
|
|
349
|
+
credentials: credentials.map(cloneCredential)
|
|
350
|
+
}, currentDocument);
|
|
351
|
+
return cloneCredential(validated);
|
|
155
352
|
});
|
|
156
353
|
}
|
|
157
354
|
/** @inheritdoc */
|
|
@@ -161,7 +358,10 @@ var OpenAICodexCredentialStore = class {
|
|
|
161
358
|
recursive: true,
|
|
162
359
|
mode: 448
|
|
163
360
|
});
|
|
164
|
-
await withFileLock(this.filename, () =>
|
|
361
|
+
await withFileLock(this.filename, async () => {
|
|
362
|
+
await rm(this.filename, { force: true });
|
|
363
|
+
await rm(this.version1BackupFilename, { force: true });
|
|
364
|
+
});
|
|
165
365
|
}
|
|
166
366
|
};
|
|
167
367
|
//#endregion
|
|
@@ -528,10 +728,8 @@ function parseOpenAICodexUsage(value) {
|
|
|
528
728
|
async function readOpenAICodexRateLimits(store) {
|
|
529
729
|
const models = createModels({ credentials: store });
|
|
530
730
|
models.setProvider(openaiCodexProvider());
|
|
531
|
-
const
|
|
532
|
-
const
|
|
533
|
-
const access = auth?.auth.apiKey;
|
|
534
|
-
const accountId = credential?.type === "oauth" ? credential.accountId : void 0;
|
|
731
|
+
const access = (await models.getAuth(OPENAI_CODEX_PROVIDER))?.auth.apiKey;
|
|
732
|
+
const accountId = access === void 0 ? void 0 : await store.accountIdForAccess(access);
|
|
535
733
|
if (access === void 0 || access.length === 0 || typeof accountId !== "string" || accountId.length === 0) throw new Error("OpenAI Codex is signed out");
|
|
536
734
|
const response = await fetch(OPENAI_CODEX_USAGE_URL, {
|
|
537
735
|
method: "GET",
|
|
@@ -568,6 +766,8 @@ const OPENAI_CODEX_AUTH_LOGIN_PATH = "/plugins/dsh-openai-codex/auth/login";
|
|
|
568
766
|
const OPENAI_CODEX_AUTH_LOGOUT_PATH = "/plugins/dsh-openai-codex/auth/logout";
|
|
569
767
|
/** Cancel only the pending authorization; never delete a stored credential. */
|
|
570
768
|
const OPENAI_CODEX_AUTH_CANCEL_PATH = "/plugins/dsh-openai-codex/auth/cancel";
|
|
769
|
+
/** List, activate, and remove stored OpenAI Codex accounts. */
|
|
770
|
+
const OPENAI_CODEX_AUTH_ACCOUNTS_PATH = "/plugins/dsh-openai-codex/auth/accounts";
|
|
571
771
|
//#endregion
|
|
572
772
|
//#region src/trusted-origins.ts
|
|
573
773
|
/** Owner-only allowlist for browser origins that may reach the Web OAuth routes. */
|
|
@@ -881,6 +1081,14 @@ var OpenAICodexWebAuth = class {
|
|
|
881
1081
|
async cancel() {
|
|
882
1082
|
await this.finishLogin("cancel");
|
|
883
1083
|
}
|
|
1084
|
+
/** Cancel pending OAuth and select one already stored account. */
|
|
1085
|
+
async activateAccount(accountKey) {
|
|
1086
|
+
return this.mutateStoredAccount(() => this.store.activate(accountKey));
|
|
1087
|
+
}
|
|
1088
|
+
/** Cancel pending OAuth and remove exactly one stored account. */
|
|
1089
|
+
async removeAccount(accountKey, replacementAccountKey) {
|
|
1090
|
+
return this.mutateStoredAccount(() => this.store.removeAccount(accountKey, replacementAccountKey));
|
|
1091
|
+
}
|
|
884
1092
|
/** Stop the owned callback listener during plugin disposal. */
|
|
885
1093
|
async dispose() {
|
|
886
1094
|
this.disposed = true;
|
|
@@ -905,6 +1113,28 @@ var OpenAICodexWebAuth = class {
|
|
|
905
1113
|
if (this.transition === transition) this.transition = void 0;
|
|
906
1114
|
}
|
|
907
1115
|
}
|
|
1116
|
+
async mutateStoredAccount(operation) {
|
|
1117
|
+
while (this.transition !== void 0) await this.transition;
|
|
1118
|
+
if (this.disposed) throw new Error("OpenAI Codex plugin disposed");
|
|
1119
|
+
const login = this.operation;
|
|
1120
|
+
this.cancelSignIn(/* @__PURE__ */ new Error("OpenAI Codex sign-in cancelled"));
|
|
1121
|
+
let result;
|
|
1122
|
+
const transition = (async () => {
|
|
1123
|
+
await login?.catch(() => void 0);
|
|
1124
|
+
this.challenge = void 0;
|
|
1125
|
+
await operation();
|
|
1126
|
+
result = await this.readStoredStatus();
|
|
1127
|
+
this.state = result;
|
|
1128
|
+
})();
|
|
1129
|
+
this.transition = transition;
|
|
1130
|
+
try {
|
|
1131
|
+
await transition;
|
|
1132
|
+
if (result === void 0) throw new Error("openai-codex: account mutation did not produce status");
|
|
1133
|
+
return result;
|
|
1134
|
+
} finally {
|
|
1135
|
+
if (this.transition === transition) this.transition = void 0;
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
908
1138
|
start() {
|
|
909
1139
|
const cancellation = new AbortController();
|
|
910
1140
|
this.cancellation = cancellation;
|
|
@@ -1153,6 +1383,44 @@ function fastModeBody(value) {
|
|
|
1153
1383
|
enabled
|
|
1154
1384
|
} : void 0;
|
|
1155
1385
|
}
|
|
1386
|
+
function accountKey(value) {
|
|
1387
|
+
return typeof value === "string" && /^acct_[A-Za-z0-9_-]{43}$/u.test(value) ? value : void 0;
|
|
1388
|
+
}
|
|
1389
|
+
function activateAccountBody(value) {
|
|
1390
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
1391
|
+
const record = value;
|
|
1392
|
+
if (Object.keys(record).length !== 1) return void 0;
|
|
1393
|
+
const parsed = accountKey(record["accountKey"]);
|
|
1394
|
+
return parsed === void 0 ? void 0 : { accountKey: parsed };
|
|
1395
|
+
}
|
|
1396
|
+
function removeAccountBody(value) {
|
|
1397
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
1398
|
+
const record = value;
|
|
1399
|
+
if (Object.keys(record).some((key) => key !== "accountKey" && key !== "replacementAccountKey")) return void 0;
|
|
1400
|
+
const selected = accountKey(record["accountKey"]);
|
|
1401
|
+
if (selected === void 0) return void 0;
|
|
1402
|
+
if (record["replacementAccountKey"] === void 0) return { accountKey: selected };
|
|
1403
|
+
const replacement = accountKey(record["replacementAccountKey"]);
|
|
1404
|
+
return replacement === void 0 ? void 0 : {
|
|
1405
|
+
accountKey: selected,
|
|
1406
|
+
replacementAccountKey: replacement
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1409
|
+
function accountMutationError(error) {
|
|
1410
|
+
const message = safeMessage(error);
|
|
1411
|
+
if (/account not found/u.test(message)) return {
|
|
1412
|
+
status: 404,
|
|
1413
|
+
error: message
|
|
1414
|
+
};
|
|
1415
|
+
if (/requires replacementAccountKey|only valid when removing/u.test(message)) return {
|
|
1416
|
+
status: 409,
|
|
1417
|
+
error: message
|
|
1418
|
+
};
|
|
1419
|
+
return {
|
|
1420
|
+
status: 500,
|
|
1421
|
+
error: message
|
|
1422
|
+
};
|
|
1423
|
+
}
|
|
1156
1424
|
/** Register the plugin-owned OAuth routes when the Web server is composed. */
|
|
1157
1425
|
function registerOpenAICodexAuthRoutes(ctx, store, trustedOriginsOverride, fastModeOverride, proxyManager, resolveProxyUrl, authorizationTimeoutMs) {
|
|
1158
1426
|
const auth = new OpenAICodexWebAuth(store, {
|
|
@@ -1177,7 +1445,11 @@ function registerOpenAICodexAuthRoutes(ctx, store, trustedOriginsOverride, fastM
|
|
|
1177
1445
|
handler: async (req, res) => {
|
|
1178
1446
|
if (req.method !== "GET") return json$4(res, 405, { error: "method not allowed" });
|
|
1179
1447
|
if (!await authorize(req, res)) return;
|
|
1180
|
-
|
|
1448
|
+
const [status, accounts] = await Promise.all([auth.status(), store.accounts()]);
|
|
1449
|
+
json$4(res, 200, {
|
|
1450
|
+
...status,
|
|
1451
|
+
accounts
|
|
1452
|
+
});
|
|
1181
1453
|
}
|
|
1182
1454
|
}),
|
|
1183
1455
|
ctx.webServer.register({
|
|
@@ -1221,6 +1493,33 @@ function registerOpenAICodexAuthRoutes(ctx, store, trustedOriginsOverride, fastM
|
|
|
1221
1493
|
}
|
|
1222
1494
|
}
|
|
1223
1495
|
}),
|
|
1496
|
+
ctx.webServer.register({
|
|
1497
|
+
kind: "exact",
|
|
1498
|
+
path: OPENAI_CODEX_AUTH_ACCOUNTS_PATH,
|
|
1499
|
+
handler: async (req, res) => {
|
|
1500
|
+
if (req.method !== "GET" && req.method !== "POST" && req.method !== "DELETE") return json$4(res, 405, { error: "method not allowed" });
|
|
1501
|
+
if (!await authorize(req, res)) return;
|
|
1502
|
+
if (req.method === "GET") return json$4(res, 200, { accounts: await store.accounts() });
|
|
1503
|
+
const type = header(req, "content-type");
|
|
1504
|
+
if (type === void 0 || !/^application\/json(?:\s*;|$)/iu.test(type.trim())) return json$4(res, 415, { error: "unsupported content type" });
|
|
1505
|
+
try {
|
|
1506
|
+
const raw = await readFastModeBody(req);
|
|
1507
|
+
if (req.method === "POST") {
|
|
1508
|
+
const body = activateAccountBody(raw);
|
|
1509
|
+
if (body === void 0) return json$4(res, 400, { error: "invalid input" });
|
|
1510
|
+
return json$4(res, 200, await auth.activateAccount(body.accountKey));
|
|
1511
|
+
}
|
|
1512
|
+
const body = removeAccountBody(raw);
|
|
1513
|
+
if (body === void 0) return json$4(res, 400, { error: "invalid input" });
|
|
1514
|
+
return json$4(res, 200, await auth.removeAccount(body.accountKey, body.replacementAccountKey));
|
|
1515
|
+
} catch (error) {
|
|
1516
|
+
if (error instanceof RangeError) return json$4(res, 413, { error: "request body too large" });
|
|
1517
|
+
if (error instanceof TypeError) return json$4(res, 400, { error: "invalid input" });
|
|
1518
|
+
const mapped = accountMutationError(error);
|
|
1519
|
+
return json$4(res, mapped.status, { error: mapped.error });
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
}),
|
|
1224
1523
|
ctx.webServer.register({
|
|
1225
1524
|
kind: "exact",
|
|
1226
1525
|
path: OPENAI_CODEX_FAST_MODE_PATH,
|
|
@@ -1510,7 +1809,10 @@ var OpenAICodexProxyManager = class {
|
|
|
1510
1809
|
agentFor(proxyUrl) {
|
|
1511
1810
|
let agent = this.agents.get(proxyUrl);
|
|
1512
1811
|
if (agent !== void 0) return agent;
|
|
1513
|
-
agent = new ProxyAgent(
|
|
1812
|
+
agent = new ProxyAgent({
|
|
1813
|
+
uri: proxyUrl,
|
|
1814
|
+
proxyTunnel: true
|
|
1815
|
+
});
|
|
1514
1816
|
this.agents.set(proxyUrl, agent);
|
|
1515
1817
|
return agent;
|
|
1516
1818
|
}
|
|
@@ -1678,7 +1980,7 @@ function registerOpenAICodexProxyRoutes(ctx, trustedOrigins, manager) {
|
|
|
1678
1980
|
//#region src/compatibility.ts
|
|
1679
1981
|
const COMPATIBILITY_SCHEMA_VERSION = 1;
|
|
1680
1982
|
const SUPPORTED_NODE_RANGE = "^22.19.0 || >=24.0.0";
|
|
1681
|
-
const SUPPORTED_DSH_PLUGIN_API_VERSION = "0.1.2-
|
|
1983
|
+
const SUPPORTED_DSH_PLUGIN_API_VERSION = "0.1.2-rc.1";
|
|
1682
1984
|
const SUPPORTED_PI_AI_RANGE = "^0.84.2";
|
|
1683
1985
|
const PI_AI_PACKAGE = "@earendil-works/pi-ai";
|
|
1684
1986
|
const DSH_PLUGIN_API_PACKAGES = [
|
|
@@ -2563,7 +2865,7 @@ function registerOpenAICodexOriginalImageRoute(ctx, trustedOrigins, assets) {
|
|
|
2563
2865
|
}
|
|
2564
2866
|
//#endregion
|
|
2565
2867
|
//#region src/version.ts
|
|
2566
|
-
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.
|
|
2868
|
+
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.26";
|
|
2567
2869
|
//#endregion
|
|
2568
2870
|
//#region src/doctor.ts
|
|
2569
2871
|
/** Secret-free diagnostics and duplicate-provider guidance. */
|
|
@@ -3576,9 +3878,8 @@ var OpenAICodexTransport = class extends Service {
|
|
|
3576
3878
|
} catch {
|
|
3577
3879
|
throw new OpenAICodexTransportError(OPENAI_CODEX_TRANSPORT_ERROR_CODES.reauthRequired);
|
|
3578
3880
|
}
|
|
3579
|
-
const refreshed = await this.credentials.read(OPENAI_CODEX_PROVIDER);
|
|
3580
3881
|
const access = auth?.auth.apiKey;
|
|
3581
|
-
const accountId =
|
|
3882
|
+
const accountId = access === void 0 ? void 0 : await this.credentials.accountIdForAccess(access);
|
|
3582
3883
|
if (typeof access !== "string" || access.length === 0 || typeof accountId !== "string" || accountId.length === 0) throw new OpenAICodexTransportError(OPENAI_CODEX_TRANSPORT_ERROR_CODES.reauthRequired);
|
|
3583
3884
|
if (isAborted(context.signal)) throw new OpenAICodexTransportError(OPENAI_CODEX_TRANSPORT_ERROR_CODES.canceled);
|
|
3584
3885
|
const traceId = randomUUID();
|
|
@@ -4394,8 +4695,7 @@ var OpenAICodexAutoReviewBackend = class {
|
|
|
4394
4695
|
}, AUTO_REVIEW_TIMEOUT_MS);
|
|
4395
4696
|
try {
|
|
4396
4697
|
const access = (await this.models.getAuth(OPENAI_CODEX_PROVIDER, { signal: controller.signal }))?.auth.apiKey;
|
|
4397
|
-
const
|
|
4398
|
-
const accountId = stored?.type === "oauth" && typeof stored.accountId === "string" ? stored.accountId : void 0;
|
|
4698
|
+
const accountId = access === void 0 ? void 0 : await this.credentialStore.accountIdForAccess(access);
|
|
4399
4699
|
if (access === void 0 || access.length === 0 || accountId === void 0 || accountId.length === 0) return { status: "unavailable" };
|
|
4400
4700
|
const response = await this.proxyManager.run(this.resolveProxyUrl(), () => fetch$1(`${OPENAI_CODEX_BASE_URL}/responses`, {
|
|
4401
4701
|
method: "POST",
|
|
@@ -5279,4 +5579,4 @@ function apply(ctx, config) {
|
|
|
5279
5579
|
scheduleCapabilities();
|
|
5280
5580
|
}
|
|
5281
5581
|
//#endregion
|
|
5282
|
-
export { OPENAI_CODEX_LOCAL_PROXY_CANDIDATES as $, assertNoOpenAICodexProviderConflict as A, logoutOpenAICodex as At, COMPATIBILITY_PACKAGES as B, OPENAI_CODEX_TRANSPORT_ERROR_CODES as C, isFastModeSessionId as Ct, isOpenAICodexTransportError as D, parseOpenAICodexUsage as Dt, OpenAICodexTransportError as E, OPENAI_CODEX_USAGE_URL as Et, checkForOpenAICodexUpdate as F,
|
|
5582
|
+
export { OPENAI_CODEX_LOCAL_PROXY_CANDIDATES as $, assertNoOpenAICodexProviderConflict as A, logoutOpenAICodex as At, COMPATIBILITY_PACKAGES as B, OPENAI_CODEX_TRANSPORT_ERROR_CODES as C, isFastModeSessionId as Ct, isOpenAICodexTransportError as D, parseOpenAICodexUsage as Dt, OpenAICodexTransportError as E, OPENAI_CODEX_USAGE_URL as Et, checkForOpenAICodexUpdate as F, OPENAI_CODEX_AUTH_FILENAME as Ft, SUPPORTED_NODE_RANGE as G, DSH_PLUGIN_API_PACKAGES as H, compareOpenAICodexVersions as I, OPENAI_CODEX_AUTH_V1_BACKUP_SUFFIX as It, detectCompatibility as J, SUPPORTED_PI_AI_RANGE as K, parseOpenAICodexUpdateResult as L, OPENAI_CODEX_PROVIDER as Lt, openAICodexConflictMessage as M, openAICodexModelCatalog as Mt, CODEX_CONNECT_VERSION as N, OPENAI_CODEX_ACCOUNT_LIMIT as Nt, VIEW_IMAGE_TOOL_NAME as O, readOpenAICodexRateLimits as Ot, OPENAI_CODEX_UPDATE_PATH as P, OPENAI_CODEX_AUTH_DOCUMENT_LIMIT as Pt, OPENAI_CODEX_PROXY_TEST_PATH as Q, parseOpenAICodexVersion as R, OpenAICodexCredentialStore as Rt, OPENAI_CODEX_TRANSPORT_API_VERSION as S, OPENAI_CODEX_FAST_MODE_MAX_SESSION_ID_LENGTH as St, OpenAICodexTransport as T, normalizeTrustedOrigin as Tt, PI_AI_PACKAGE as U, COMPATIBILITY_SCHEMA_VERSION as V, SUPPORTED_DSH_PLUGIN_API_VERSION as W, readInstalledPackageVersion as X, evaluateCompatibility as Y, OPENAI_CODEX_PROXY_DETECT_PATH as Z, OPENAI_CODEX_IMAGE_MAX_COUNT as _, resolveOpenAICodexProxyUrl as _t, name as a, listOpenAICodexProxyCandidates as at, OPENAI_CODEX_IMAGE_PROMPT_MAX_LENGTH as b, FastModeRegistry as bt, migrateOpenAICodexSearchHistory as c, DEFAULT_OPENAI_CODEX_SEARCH_MAX_OUTPUT_TOKENS as ct, OPENAI_CODEX_BASE_URL as d, DEFAULT_OPENAI_CODEX_SETTINGS as dt, OPENAI_CODEX_PROXY_CANDIDATE_LIMIT as et, OPENAI_CODEX_SEARCH_PROVIDER as f, OPENAI_CODEX_SETTINGS_NAMESPACE as ft, OPENAI_CODEX_IMAGE_GENERATION_URL as g, normalizeOpenAICodexProxyUrl as gt, mapOpenAICodexSearchResponse as h, isValidOpenAICodexProxyUrl as ht, inject as i, detectOpenAICodexProxies as it, diagnoseOpenAICodex as j, openAICodexAuthStatus as jt, IMAGE_GENERATE_TOOL_NAME as k, loginOpenAICodex as kt, CODEX_AUTO_REVIEW_MODEL as l, DEFAULT_OPENAI_CODEX_SEARCH_MODE as lt, OpenAICodexSearchProvider as m, isValidOpenAICodexContextWindowOverrides as mt, OPENAI_CODEX_SETTINGS_NS as n, OPENAI_CODEX_PROXY_PROBE_URL as nt, OPENAI_CODEX_HISTORY_BACKUP_SUFFIX as o, DEFAULT_OPENAI_CODEX_PROXY_URL as ot, OPENAI_CODEX_SEARCH_URL as p, decodeOpenAICodexSettings as pt, assessCompatibility as q, apply as r, OpenAICodexProxyManager as rt, OPENAI_CODEX_SEARCH_MODEL_REQUEST_EVENT as s, DEFAULT_OPENAI_CODEX_SEARCH_CONTEXT_SIZE as st, Config as t, OPENAI_CODEX_PROXY_PROBE_TIMEOUT_MS as tt, probeCodexAutoReview as u, DEFAULT_OPENAI_CODEX_SEARCH_MODEL as ut, OPENAI_CODEX_IMAGE_MAX_ERROR_BYTES as v, resolveOpenAICodexSettings as vt, OPENAI_CODEX_TRANSPORT_SERVICE as w, OpenAICodexTrustedOriginsStore as wt, OPENAI_CODEX_IMAGE_REQUEST_TIMEOUT_MS as x, OPENAI_CODEX_FAST_MODE_MAX_SESSIONS as xt, OPENAI_CODEX_IMAGE_MAX_RESPONSE_BYTES as y, OPENAI_CODEX_FAST_MODE_PATH as yt, COMPATIBILITY_CONTRACT as z, openAICodexAuthPath as zt };
|
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.
|
|
5
|
+
"version": "0.1.0-alpha.4.26",
|
|
6
6
|
"author": "Frank Song",
|
|
7
7
|
"contributors": [
|
|
8
8
|
"Yan-Zero (original dsh-codex author)"
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"NOTICE"
|
|
79
79
|
],
|
|
80
80
|
"dependencies": {
|
|
81
|
-
"undici": "^
|
|
81
|
+
"undici": "^8.10.0"
|
|
82
82
|
},
|
|
83
83
|
"license": "Apache-2.0",
|
|
84
84
|
"dsh": {
|
|
@@ -104,24 +104,24 @@
|
|
|
104
104
|
"peerDependencies": {
|
|
105
105
|
"@earendil-works/pi-ai": "^0.84.2",
|
|
106
106
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
107
|
-
"@deepseek-ai/dsh-agent": "0.1.2-
|
|
108
|
-
"@deepseek-ai/dsh-atomic-write": "0.1.2-
|
|
109
|
-
"@deepseek-ai/dsh-attachment": "0.1.2-
|
|
110
|
-
"@deepseek-ai/dsh-client-ui-layout": "0.1.2-
|
|
111
|
-
"@deepseek-ai/dsh-client-ui-primitives": "0.1.2-
|
|
112
|
-
"@deepseek-ai/dsh-client-ui-tool": "0.1.2-
|
|
113
|
-
"@deepseek-ai/dsh-commands": "0.1.2-
|
|
114
|
-
"@deepseek-ai/dsh-home-paths": "0.1.2-
|
|
115
|
-
"@deepseek-ai/dsh-host-webserver": "0.1.2-
|
|
116
|
-
"@deepseek-ai/dsh-invariants": "0.1.2-
|
|
117
|
-
"@deepseek-ai/dsh-llm": "0.1.2-
|
|
118
|
-
"@deepseek-ai/dsh-llm-pi-ai": "0.1.2-
|
|
119
|
-
"@deepseek-ai/dsh-fs": "0.1.2-
|
|
120
|
-
"@deepseek-ai/dsh-session": "0.1.2-
|
|
121
|
-
"@deepseek-ai/dsh-settings": "0.1.2-
|
|
122
|
-
"@deepseek-ai/dsh-tools": "0.1.2-
|
|
123
|
-
"@deepseek-ai/dsh-util-values": "0.1.2-
|
|
124
|
-
"@deepseek-ai/dsh-web": "0.1.2-
|
|
107
|
+
"@deepseek-ai/dsh-agent": "0.1.2-rc.1",
|
|
108
|
+
"@deepseek-ai/dsh-atomic-write": "0.1.2-rc.1",
|
|
109
|
+
"@deepseek-ai/dsh-attachment": "0.1.2-rc.1",
|
|
110
|
+
"@deepseek-ai/dsh-client-ui-layout": "0.1.2-rc.1",
|
|
111
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.1.2-rc.1",
|
|
112
|
+
"@deepseek-ai/dsh-client-ui-tool": "0.1.2-rc.1",
|
|
113
|
+
"@deepseek-ai/dsh-commands": "0.1.2-rc.1",
|
|
114
|
+
"@deepseek-ai/dsh-home-paths": "0.1.2-rc.1",
|
|
115
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.2-rc.1",
|
|
116
|
+
"@deepseek-ai/dsh-invariants": "0.1.2-rc.1",
|
|
117
|
+
"@deepseek-ai/dsh-llm": "0.1.2-rc.1",
|
|
118
|
+
"@deepseek-ai/dsh-llm-pi-ai": "0.1.2-rc.1",
|
|
119
|
+
"@deepseek-ai/dsh-fs": "0.1.2-rc.1",
|
|
120
|
+
"@deepseek-ai/dsh-session": "0.1.2-rc.1",
|
|
121
|
+
"@deepseek-ai/dsh-settings": "0.1.2-rc.1",
|
|
122
|
+
"@deepseek-ai/dsh-tools": "0.1.2-rc.1",
|
|
123
|
+
"@deepseek-ai/dsh-util-values": "0.1.2-rc.1",
|
|
124
|
+
"@deepseek-ai/dsh-web": "0.1.2-rc.1",
|
|
125
125
|
"@deepseek-ai/schemastery": "^3.18.2",
|
|
126
126
|
"react": "^18.2.0"
|
|
127
127
|
},
|
|
@@ -135,61 +135,61 @@
|
|
|
135
135
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
136
136
|
"@deepseek-ai/cordis-plugin-include": "1.0.7",
|
|
137
137
|
"@deepseek-ai/cordis-plugin-loader": "1.0.3",
|
|
138
|
-
"@deepseek-ai/dsh-agent": "0.1.2-
|
|
139
|
-
"@deepseek-ai/dsh-agent-default-model": "0.1.2-
|
|
140
|
-
"@deepseek-ai/dsh-agent-presets": "0.1.2-
|
|
141
|
-
"@deepseek-ai/dsh-api-remotes": "0.1.2-
|
|
142
|
-
"@deepseek-ai/dsh-api-gateway": "0.1.2-
|
|
143
|
-
"@deepseek-ai/dsh-api-session-controller": "0.1.2-
|
|
144
|
-
"@deepseek-ai/dsh-atomic-write": "0.1.2-
|
|
145
|
-
"@deepseek-ai/dsh-attachment": "0.1.2-
|
|
146
|
-
"@deepseek-ai/dsh-attachment-local": "0.1.2-
|
|
147
|
-
"@deepseek-ai/dsh-authorization": "0.1.2-
|
|
148
|
-
"@deepseek-ai/dsh-client-locale": "0.1.2-
|
|
149
|
-
"@deepseek-ai/dsh-client-connection": "0.1.2-
|
|
150
|
-
"@deepseek-ai/dsh-client-store": "0.1.2-
|
|
151
|
-
"@deepseek-ai/dsh-client-ui-conversation": "0.1.2-
|
|
152
|
-
"@deepseek-ai/dsh-client-ui-layout": "0.1.2-
|
|
153
|
-
"@deepseek-ai/dsh-client-ui-primitives": "0.1.2-
|
|
154
|
-
"@deepseek-ai/dsh-client-ui-model-selection": "0.1.2-
|
|
155
|
-
"@deepseek-ai/dsh-client-ui-renderer": "0.1.2-
|
|
156
|
-
"@deepseek-ai/dsh-client-ui-settings": "0.1.2-
|
|
157
|
-
"@deepseek-ai/dsh-client-ui-settings-models": "0.1.2-
|
|
158
|
-
"@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.2-
|
|
159
|
-
"@deepseek-ai/dsh-client-ui-session": "0.1.2-
|
|
160
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.1.2-
|
|
161
|
-
"@deepseek-ai/dsh-client-ui-tool": "0.1.2-
|
|
162
|
-
"@deepseek-ai/dsh-code-runtime": "0.1.2-
|
|
163
|
-
"@deepseek-ai/dsh-commands": "0.1.2-
|
|
164
|
-
"@deepseek-ai/dsh-file-reference": "0.1.2-
|
|
165
|
-
"@deepseek-ai/dsh-fs": "0.1.2-
|
|
166
|
-
"@deepseek-ai/dsh-fs-local": "0.1.2-
|
|
167
|
-
"@deepseek-ai/dsh-home-paths": "0.1.2-
|
|
168
|
-
"@deepseek-ai/dsh-host-webserver": "0.1.2-
|
|
169
|
-
"@deepseek-ai/dsh-invariants": "0.1.2-
|
|
170
|
-
"@deepseek-ai/dsh-llm": "0.1.2-
|
|
171
|
-
"@deepseek-ai/dsh-llm-pi-ai": "0.1.2-
|
|
172
|
-
"@deepseek-ai/dsh-launch-environment": "0.1.2-
|
|
173
|
-
"@deepseek-ai/dsh-native-command": "0.1.2-
|
|
174
|
-
"@deepseek-ai/dsh-sandbox": "0.1.2-
|
|
175
|
-
"@deepseek-ai/dsh-scope": "0.1.2-
|
|
176
|
-
"@deepseek-ai/dsh-session": "0.1.2-
|
|
177
|
-
"@deepseek-ai/dsh-session-persistence": "0.1.2-
|
|
178
|
-
"@deepseek-ai/dsh-session-projection": "0.1.2-
|
|
179
|
-
"@deepseek-ai/dsh-session-query": "0.1.2-
|
|
180
|
-
"@deepseek-ai/dsh-session-title": "0.1.2-
|
|
181
|
-
"@deepseek-ai/dsh-settings": "0.1.2-
|
|
182
|
-
"@deepseek-ai/dsh-skill": "0.1.2-
|
|
183
|
-
"@deepseek-ai/dsh-storage": "0.1.2-
|
|
184
|
-
"@deepseek-ai/dsh-storage-domain": "0.1.2-
|
|
185
|
-
"@deepseek-ai/dsh-subagent": "0.1.2-
|
|
186
|
-
"@deepseek-ai/dsh-system-prompt": "0.1.2-
|
|
187
|
-
"@deepseek-ai/dsh-tools": "0.1.2-
|
|
188
|
-
"@deepseek-ai/dsh-typert-registry": "0.1.2-
|
|
189
|
-
"@deepseek-ai/dsh-user-approval": "0.1.2-
|
|
190
|
-
"@deepseek-ai/dsh-util-values": "0.1.2-
|
|
191
|
-
"@deepseek-ai/dsh-web": "0.1.2-
|
|
192
|
-
"@deepseek-ai/dsh-workspace": "0.1.2-
|
|
138
|
+
"@deepseek-ai/dsh-agent": "0.1.2-rc.1",
|
|
139
|
+
"@deepseek-ai/dsh-agent-default-model": "0.1.2-rc.1",
|
|
140
|
+
"@deepseek-ai/dsh-agent-presets": "0.1.2-rc.1",
|
|
141
|
+
"@deepseek-ai/dsh-api-remotes": "0.1.2-rc.1",
|
|
142
|
+
"@deepseek-ai/dsh-api-gateway": "0.1.2-rc.1",
|
|
143
|
+
"@deepseek-ai/dsh-api-session-controller": "0.1.2-rc.1",
|
|
144
|
+
"@deepseek-ai/dsh-atomic-write": "0.1.2-rc.1",
|
|
145
|
+
"@deepseek-ai/dsh-attachment": "0.1.2-rc.1",
|
|
146
|
+
"@deepseek-ai/dsh-attachment-local": "0.1.2-rc.1",
|
|
147
|
+
"@deepseek-ai/dsh-authorization": "0.1.2-rc.1",
|
|
148
|
+
"@deepseek-ai/dsh-client-locale": "0.1.2-rc.1",
|
|
149
|
+
"@deepseek-ai/dsh-client-connection": "0.1.2-rc.1",
|
|
150
|
+
"@deepseek-ai/dsh-client-store": "0.1.2-rc.1",
|
|
151
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.1.2-rc.1",
|
|
152
|
+
"@deepseek-ai/dsh-client-ui-layout": "0.1.2-rc.1",
|
|
153
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.1.2-rc.1",
|
|
154
|
+
"@deepseek-ai/dsh-client-ui-model-selection": "0.1.2-rc.1",
|
|
155
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.1.2-rc.1",
|
|
156
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.2-rc.1",
|
|
157
|
+
"@deepseek-ai/dsh-client-ui-settings-models": "0.1.2-rc.1",
|
|
158
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.2-rc.1",
|
|
159
|
+
"@deepseek-ai/dsh-client-ui-session": "0.1.2-rc.1",
|
|
160
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.2-rc.1",
|
|
161
|
+
"@deepseek-ai/dsh-client-ui-tool": "0.1.2-rc.1",
|
|
162
|
+
"@deepseek-ai/dsh-code-runtime": "0.1.2-rc.1",
|
|
163
|
+
"@deepseek-ai/dsh-commands": "0.1.2-rc.1",
|
|
164
|
+
"@deepseek-ai/dsh-file-reference": "0.1.2-rc.1",
|
|
165
|
+
"@deepseek-ai/dsh-fs": "0.1.2-rc.1",
|
|
166
|
+
"@deepseek-ai/dsh-fs-local": "0.1.2-rc.1",
|
|
167
|
+
"@deepseek-ai/dsh-home-paths": "0.1.2-rc.1",
|
|
168
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.2-rc.1",
|
|
169
|
+
"@deepseek-ai/dsh-invariants": "0.1.2-rc.1",
|
|
170
|
+
"@deepseek-ai/dsh-llm": "0.1.2-rc.1",
|
|
171
|
+
"@deepseek-ai/dsh-llm-pi-ai": "0.1.2-rc.1",
|
|
172
|
+
"@deepseek-ai/dsh-launch-environment": "0.1.2-rc.1",
|
|
173
|
+
"@deepseek-ai/dsh-native-command": "0.1.2-rc.1",
|
|
174
|
+
"@deepseek-ai/dsh-sandbox": "0.1.2-rc.1",
|
|
175
|
+
"@deepseek-ai/dsh-scope": "0.1.2-rc.1",
|
|
176
|
+
"@deepseek-ai/dsh-session": "0.1.2-rc.1",
|
|
177
|
+
"@deepseek-ai/dsh-session-persistence": "0.1.2-rc.1",
|
|
178
|
+
"@deepseek-ai/dsh-session-projection": "0.1.2-rc.1",
|
|
179
|
+
"@deepseek-ai/dsh-session-query": "0.1.2-rc.1",
|
|
180
|
+
"@deepseek-ai/dsh-session-title": "0.1.2-rc.1",
|
|
181
|
+
"@deepseek-ai/dsh-settings": "0.1.2-rc.1",
|
|
182
|
+
"@deepseek-ai/dsh-skill": "0.1.2-rc.1",
|
|
183
|
+
"@deepseek-ai/dsh-storage": "0.1.2-rc.1",
|
|
184
|
+
"@deepseek-ai/dsh-storage-domain": "0.1.2-rc.1",
|
|
185
|
+
"@deepseek-ai/dsh-subagent": "0.1.2-rc.1",
|
|
186
|
+
"@deepseek-ai/dsh-system-prompt": "0.1.2-rc.1",
|
|
187
|
+
"@deepseek-ai/dsh-tools": "0.1.2-rc.1",
|
|
188
|
+
"@deepseek-ai/dsh-typert-registry": "0.1.2-rc.1",
|
|
189
|
+
"@deepseek-ai/dsh-user-approval": "0.1.2-rc.1",
|
|
190
|
+
"@deepseek-ai/dsh-util-values": "0.1.2-rc.1",
|
|
191
|
+
"@deepseek-ai/dsh-web": "0.1.2-rc.1",
|
|
192
|
+
"@deepseek-ai/dsh-workspace": "0.1.2-rc.1",
|
|
193
193
|
"@deepseek-ai/schemastery": "3.18.2",
|
|
194
194
|
"@testing-library/react": "^16.3.2",
|
|
195
195
|
"@types/node": "^22.20.0",
|