dsh-codex-connect 0.1.0-alpha.4.4 → 0.1.0-alpha.4.6
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 +1 -1
- package/README.i18n.yaml +2 -2
- package/README.md +27 -1
- package/docs/README.zh.md +27 -1
- package/docs/assets/hero.jpg +0 -0
- package/docs/assets/model-selector.jpg +0 -0
- package/docs/assets/oauth-status.jpg +0 -0
- package/docs/assets/plugin-configuration.jpg +0 -0
- package/lib/bin.js +44 -5
- package/lib/client.js +6 -4
- package/lib/index.js +1 -1
- package/lib/{src-BY1nv_E6.js → src-KKqkbCFT.js} +31 -3
- package/package.json +2 -1
package/INSTALL.md
CHANGED
|
@@ -19,7 +19,7 @@ Install `dsh-codex-connect` into one requested DeepSeek Harness profile without
|
|
|
19
19
|
dsh plugin --profile web add dsh-codex-connect@alpha
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
After `0.1.0-alpha.4.6` is published, pin it exactly with `dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.6`. If npm is unavailable after its matching GitHub prerelease is created, use `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.6'`.
|
|
23
23
|
|
|
24
24
|
3. Run `dsh --profile web --dump-config` and require exactly one `llm-openai-codex` row loading `dsh-codex-connect`.
|
|
25
25
|
4. Confirm the effective `agent-default-model` and `web.searchProvider` values are unchanged from before installation.
|
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: 6eedfff99162f49458c9fc6f5fc4dff502aa7dfc
|
|
6
|
+
docs/README.zh.md: 3fa64da86d3c1f1305f67a5e29e4255ca309eccb
|
package/README.md
CHANGED
|
@@ -6,10 +6,34 @@ English | [中文](docs/README.zh.md)
|
|
|
6
6
|
|
|
7
7
|
Connect your ChatGPT subscription to DeepSeek Harness with OAuth, user-controlled defaults, Harness-native approvals, diagnostics, and reliable session recovery.
|
|
8
8
|
|
|
9
|
+
<p align="center">
|
|
10
|
+
<img src="https://raw.githubusercontent.com/franksong2702/dsh-codex-connect/main/docs/assets/hero.jpg" alt="Codex Connect — ChatGPT OAuth for DeepSeek Harness" width="100%">
|
|
11
|
+
</p>
|
|
12
|
+
|
|
9
13
|
`dsh-codex-connect` adds the `openai-codex` model catalog and a separate ChatGPT OAuth login. Models run through Harness's normal LLM service, so streaming, tool calls, reasoning replay, compaction, filesystem controls, permission gates, and approval prompts remain Harness-owned. It does not turn a ChatGPT subscription into an OpenAI Platform API credential.
|
|
10
14
|
|
|
11
15
|
Installation is additive. The bundle does not replace the current default model or search route, and its standalone search provider and `view_image` tool are disabled until explicitly enabled.
|
|
12
16
|
|
|
17
|
+
## See it in Harness
|
|
18
|
+
|
|
19
|
+
Sign in and manage the plugin from **Settings → Plugins → Plugin configuration → Codex Connect**.
|
|
20
|
+
|
|
21
|
+
<p align="center">
|
|
22
|
+
<img src="https://raw.githubusercontent.com/franksong2702/dsh-codex-connect/main/docs/assets/oauth-status.jpg" alt="Codex Connect ChatGPT OAuth status inside Harness plugin configuration" width="720">
|
|
23
|
+
</p>
|
|
24
|
+
|
|
25
|
+
Optional Codex search and `view_image` capabilities remain explicit, profile-scoped choices:
|
|
26
|
+
|
|
27
|
+
<p align="center">
|
|
28
|
+
<img src="https://raw.githubusercontent.com/franksong2702/dsh-codex-connect/main/docs/assets/plugin-configuration.jpg" alt="Codex Connect optional capability settings in DeepSeek Harness" width="720">
|
|
29
|
+
</p>
|
|
30
|
+
|
|
31
|
+
Codex models then appear in Harness's normal model picker alongside the existing providers:
|
|
32
|
+
|
|
33
|
+
<p align="center">
|
|
34
|
+
<img src="https://raw.githubusercontent.com/franksong2702/dsh-codex-connect/main/docs/assets/model-selector.jpg" alt="OpenAI Codex models in the DeepSeek Harness model picker" width="320">
|
|
35
|
+
</p>
|
|
36
|
+
|
|
13
37
|
## Install
|
|
14
38
|
|
|
15
39
|
```sh
|
|
@@ -17,7 +41,7 @@ dsh plugin --profile web add dsh-codex-connect@alpha
|
|
|
17
41
|
dsh web
|
|
18
42
|
```
|
|
19
43
|
|
|
20
|
-
|
|
44
|
+
After `0.1.0-alpha.4.6` is published, pin it exactly with `dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.6`. If npm is unavailable after its matching GitHub prerelease is created, use `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.6'`. From a DeepSeek Harness source checkout, prefix commands with `pnpm`. For a local checkout, install `link:/absolute/path/to/dsh-codex-connect`.
|
|
21
45
|
|
|
22
46
|
Sign in from **Settings → Plugins → Plugin configuration → Codex Connect → Sign in with ChatGPT**, or use the CLI:
|
|
23
47
|
|
|
@@ -29,6 +53,8 @@ dsh plugin --profile web exec dsh-codex-connect doctor
|
|
|
29
53
|
|
|
30
54
|
The doctor command reads process and filesystem metadata only. It never opens the OAuth document or prints a token, authorization URL, authorization code, account id, or auth-file content.
|
|
31
55
|
|
|
56
|
+
For automation, `doctor --json` emits exactly one secret-free JSON document with schema version 1, package/version/Node metadata, credential-file state and safe mode, capabilities, conflict status, and hints; it omits the absolute credential path and OAuth/account/expiry data. `status --json` emits only signed-in or signed-out state with package metadata. `doctor --json` reads metadata only; `status --json` reads the credential solely to determine sign-in state, but neither mode prints credential contents or starts OAuth. Signed-out status still exits with code 1.
|
|
57
|
+
|
|
32
58
|
## Explicit configuration
|
|
33
59
|
|
|
34
60
|
Open **Settings → Plugins → Plugin configuration → Codex Connect** to manage the ChatGPT account and optional capabilities in one card. Changes use Harness's revision-fenced settings store and apply live. **Save changes** affects only this plugin's capability section; it never selects a default model or global search route.
|
package/docs/README.zh.md
CHANGED
|
@@ -6,10 +6,34 @@
|
|
|
6
6
|
|
|
7
7
|
通过 OAuth 将你的 ChatGPT 订阅连接到 DeepSeek Harness,同时保留用户自主默认项、Harness 原生审批、非敏感诊断和可靠的会话恢复。
|
|
8
8
|
|
|
9
|
+
<p align="center">
|
|
10
|
+
<img src="https://raw.githubusercontent.com/franksong2702/dsh-codex-connect/main/docs/assets/hero.jpg" alt="Codex Connect — 通过 ChatGPT OAuth 连接 DeepSeek Harness" width="100%">
|
|
11
|
+
</p>
|
|
12
|
+
|
|
9
13
|
`dsh-codex-connect` 提供 `openai-codex` 模型目录和独立的 ChatGPT OAuth 登录。模型仍走 Harness 标准 LLM 服务,因此流式输出、工具调用、reasoning replay、压缩、文件系统控制、权限门禁和审批提示仍由 Harness 负责。ChatGPT 订阅不会因此变成 OpenAI Platform API 凭据。
|
|
10
14
|
|
|
11
15
|
安装是增量的:bundle 不会替换当前主模型或搜索路由;独立搜索提供方和 `view_image` 工具也默认关闭,必须显式开启。
|
|
12
16
|
|
|
17
|
+
## 在 Harness 中的样子
|
|
18
|
+
|
|
19
|
+
在 **设置 → 插件 → 插件配置 → Codex Connect** 中登录并管理插件。
|
|
20
|
+
|
|
21
|
+
<p align="center">
|
|
22
|
+
<img src="https://raw.githubusercontent.com/franksong2702/dsh-codex-connect/main/docs/assets/oauth-status.jpg" alt="Harness 插件配置中的 Codex Connect ChatGPT OAuth 状态" width="720">
|
|
23
|
+
</p>
|
|
24
|
+
|
|
25
|
+
Codex 搜索与 `view_image` 都是显式、按 profile 控制的可选能力:
|
|
26
|
+
|
|
27
|
+
<p align="center">
|
|
28
|
+
<img src="https://raw.githubusercontent.com/franksong2702/dsh-codex-connect/main/docs/assets/plugin-configuration.jpg" alt="DeepSeek Harness 中的 Codex Connect 可选能力设置" width="720">
|
|
29
|
+
</p>
|
|
30
|
+
|
|
31
|
+
Codex 模型会和现有提供方一起出现在 Harness 原生模型选择器中:
|
|
32
|
+
|
|
33
|
+
<p align="center">
|
|
34
|
+
<img src="https://raw.githubusercontent.com/franksong2702/dsh-codex-connect/main/docs/assets/model-selector.jpg" alt="DeepSeek Harness 模型选择器中的 OpenAI Codex 模型" width="320">
|
|
35
|
+
</p>
|
|
36
|
+
|
|
13
37
|
## 安装
|
|
14
38
|
|
|
15
39
|
```sh
|
|
@@ -17,7 +41,7 @@ dsh plugin --profile web add dsh-codex-connect@alpha
|
|
|
17
41
|
dsh web
|
|
18
42
|
```
|
|
19
43
|
|
|
20
|
-
|
|
44
|
+
在 `0.1.0-alpha.4.6` 发布后,如需精确固定此版本,使用 `dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.6`。在对应 GitHub prerelease 已创建且 npm 不可用时,可使用 `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.6'`。在 DeepSeek Harness 源码 checkout 中运行时,在命令前加 `pnpm`。本地开发可安装 `link:/absolute/path/to/dsh-codex-connect`。
|
|
21
45
|
|
|
22
46
|
可在 **设置 → 插件 → 插件配置 → Codex Connect → 使用 ChatGPT 登录**,也可使用 CLI:
|
|
23
47
|
|
|
@@ -29,6 +53,8 @@ dsh plugin --profile web exec dsh-codex-connect doctor
|
|
|
29
53
|
|
|
30
54
|
`doctor` 只读取进程与文件系统元数据,不打开 OAuth 文件,也不会输出 token、授权 URL、授权码、账户 ID 或认证文件内容。
|
|
31
55
|
|
|
56
|
+
供脚本使用时,`doctor --json` 只输出一条可解析的非敏感 JSON,包含 schema version 1、包/版本/Node 信息、认证文件状态与安全 mode、能力、冲突状态和提示;它省略认证文件绝对路径以及 OAuth、账户和过期时间信息。`status --json` 只输出 signed-in 或 signed-out 状态及包元数据。`doctor --json` 只读取元数据;`status --json` 仅为判断登录态读取认证文件,但两者都不会输出认证文件内容或启动 OAuth;signed-out 状态仍返回退出码 1。
|
|
57
|
+
|
|
32
58
|
## 显式配置
|
|
33
59
|
|
|
34
60
|
打开 **设置 → 插件 → 插件配置 → Codex Connect**,可以在同一张卡片中管理 ChatGPT 账户和可选能力。更改通过 Harness 带 revision 防护的设置存储保存,并即时生效;**保存更改**只影响本插件的能力配置,绝不会选择默认模型或全局搜索路由。
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/lib/bin.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { A as
|
|
2
|
+
import { A as loginOpenAICodex, E as CODEX_CONNECT_VERSION, I as openAICodexAuthPath, M as openAICodexAuthStatus, j as logoutOpenAICodex, w as diagnoseOpenAICodex } from "./src-KKqkbCFT.js";
|
|
3
3
|
import { spawn } from "node:child_process";
|
|
4
4
|
import { realpathSync } from "node:fs";
|
|
5
5
|
import { createInterface } from "node:readline/promises";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
//#region src/bin.ts
|
|
8
8
|
/** Standalone credential CLI for the optional OpenAI Codex bundle. */
|
|
9
|
+
const JSON_SCHEMA_VERSION = 1;
|
|
9
10
|
/** Open one trusted HTTPS URL with the platform browser, best effort. */
|
|
10
11
|
function openBrowser(rawUrl) {
|
|
11
12
|
const url = new URL(rawUrl);
|
|
@@ -63,16 +64,39 @@ async function answerPrompt(prompt, deviceCode, question) {
|
|
|
63
64
|
/** Print the standalone command help. */
|
|
64
65
|
function printHelp() {
|
|
65
66
|
process.stdout.write([
|
|
66
|
-
"Usage: dsh-codex-connect <doctor|login|logout|status> [--device-code]",
|
|
67
|
+
"Usage: dsh-codex-connect <doctor|login|logout|status> [--device-code|--json]",
|
|
67
68
|
"",
|
|
68
69
|
" doctor inspect secret-free runtime and OAuth file metadata",
|
|
69
70
|
" login sign in with a separate ChatGPT OAuth session",
|
|
70
71
|
" logout remove the dsh credential without changing ~/.codex",
|
|
71
72
|
" status report non-secret dsh credential state",
|
|
72
73
|
" --device-code use headless device-code login (login only)",
|
|
74
|
+
" --json emit one secret-free JSON document (doctor/status only)",
|
|
73
75
|
""
|
|
74
76
|
].join("\n"));
|
|
75
77
|
}
|
|
78
|
+
function doctorExitCode(report) {
|
|
79
|
+
return report.credentialFile.state === "permissions-too-broad" || report.credentialFile.state === "not-a-regular-file" || report.credentialFile.state === "unreadable-metadata" ? 1 : 0;
|
|
80
|
+
}
|
|
81
|
+
/** Project the diagnostic report without its absolute credential pathname. */
|
|
82
|
+
function doctorJson(report) {
|
|
83
|
+
return {
|
|
84
|
+
schemaVersion: JSON_SCHEMA_VERSION,
|
|
85
|
+
package: report.package,
|
|
86
|
+
version: report.version,
|
|
87
|
+
node: report.node,
|
|
88
|
+
credentialFile: {
|
|
89
|
+
state: report.credentialFile.state,
|
|
90
|
+
...report.credentialFile.mode === void 0 ? {} : { mode: report.credentialFile.mode }
|
|
91
|
+
},
|
|
92
|
+
capabilities: report.capabilities,
|
|
93
|
+
providerConflict: report.providerConflict,
|
|
94
|
+
hints: report.hints
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function printJson(value) {
|
|
98
|
+
process.stdout.write(`${JSON.stringify(value)}\n`);
|
|
99
|
+
}
|
|
76
100
|
/** Execute one boot-free credential command. */
|
|
77
101
|
async function run(argv) {
|
|
78
102
|
if (argv.length === 0 || argv[0] === "--help" || argv[0] === "-h") {
|
|
@@ -85,7 +109,9 @@ async function run(argv) {
|
|
|
85
109
|
return 1;
|
|
86
110
|
}
|
|
87
111
|
const action = rawAction;
|
|
88
|
-
|
|
112
|
+
const deviceCode = flags.includes("--device-code");
|
|
113
|
+
const jsonOutput = flags.includes("--json");
|
|
114
|
+
if (flags.filter((flag) => flag !== "--device-code" && flag !== "--json").length > 0 || deviceCode && action !== "login" || jsonOutput && (action === "login" || action === "logout" || deviceCode)) {
|
|
89
115
|
process.stderr.write(`dsh-codex-connect: invalid options for ${action}: ${flags.join(" ")}\n`);
|
|
90
116
|
return 1;
|
|
91
117
|
}
|
|
@@ -93,6 +119,10 @@ async function run(argv) {
|
|
|
93
119
|
switch (action) {
|
|
94
120
|
case "doctor": {
|
|
95
121
|
const report = await diagnoseOpenAICodex();
|
|
122
|
+
if (jsonOutput) {
|
|
123
|
+
printJson(doctorJson(report));
|
|
124
|
+
return doctorExitCode(report);
|
|
125
|
+
}
|
|
96
126
|
process.stdout.write([
|
|
97
127
|
`Codex Connect ${report.version} on ${report.node}`,
|
|
98
128
|
`OAuth file metadata: ${report.credentialFile.state} (${report.credentialFile.path})`,
|
|
@@ -101,10 +131,19 @@ async function run(argv) {
|
|
|
101
131
|
...report.hints.map((hint) => `Hint: ${hint}`),
|
|
102
132
|
""
|
|
103
133
|
].join("\n"));
|
|
104
|
-
return report
|
|
134
|
+
return doctorExitCode(report);
|
|
105
135
|
}
|
|
106
136
|
case "status": {
|
|
107
137
|
const status = await openAICodexAuthStatus();
|
|
138
|
+
if (jsonOutput) {
|
|
139
|
+
printJson({
|
|
140
|
+
schemaVersion: JSON_SCHEMA_VERSION,
|
|
141
|
+
package: "dsh-codex-connect",
|
|
142
|
+
version: CODEX_CONNECT_VERSION,
|
|
143
|
+
status: status.authenticated ? "signed-in" : "signed-out"
|
|
144
|
+
});
|
|
145
|
+
return status.authenticated ? 0 : 1;
|
|
146
|
+
}
|
|
108
147
|
if (!status.authenticated) {
|
|
109
148
|
process.stdout.write("Codex Connect: signed out\n");
|
|
110
149
|
return 1;
|
|
@@ -125,7 +164,7 @@ async function run(argv) {
|
|
|
125
164
|
});
|
|
126
165
|
try {
|
|
127
166
|
await loginOpenAICodex({
|
|
128
|
-
prompt: (prompt) => answerPrompt(prompt,
|
|
167
|
+
prompt: (prompt) => answerPrompt(prompt, deviceCode, (text, options) => readline.question(text, options)),
|
|
129
168
|
notify: (event) => notify(event, true)
|
|
130
169
|
});
|
|
131
170
|
} finally {
|
package/lib/client.js
CHANGED
|
@@ -666,7 +666,7 @@ window.__ModuleLoader__.load({
|
|
|
666
666
|
height: 9,
|
|
667
667
|
borderRadius: "50%",
|
|
668
668
|
flex: "0 0 auto",
|
|
669
|
-
background: status === "signed-in" ? "var(--dsw-alias-state-success-primary, #22a06b)" : status === "error" ? "var(--dsw-alias-state-error-primary, #d92d20)" : status === "signing-in" || status === "loading" ? "var(--dsw-alias-brand-primary, #1677ff)" : "var(--dsw-alias-label-dimmed, #9aa0a6)"
|
|
669
|
+
background: status === "signed-in" ? "var(--dsw-alias-state-success-primary, #22a06b)" : status === "error" || status === "reauth-required" ? "var(--dsw-alias-state-error-primary, #d92d20)" : status === "signing-in" || status === "loading" ? "var(--dsw-alias-brand-primary, #1677ff)" : "var(--dsw-alias-label-dimmed, #9aa0a6)"
|
|
670
670
|
};
|
|
671
671
|
}
|
|
672
672
|
async function jsonRequest(path, method = "GET", signal) {
|
|
@@ -768,7 +768,7 @@ window.__ModuleLoader__.load({
|
|
|
768
768
|
if (mounted.current) setBusy(false);
|
|
769
769
|
}
|
|
770
770
|
};
|
|
771
|
-
const label = status.status === "signed-in" ? t("signedIn") : status.status === "loading" ? t("loadingAccount") : status.status === "signing-in" ? t("signingIn") : status.status === "error" ? t("requestFailed") : t("signedOut");
|
|
771
|
+
const label = status.status === "signed-in" ? t("signedIn") : status.status === "loading" ? t("loadingAccount") : status.status === "signing-in" ? t("signingIn") : status.status === "reauth-required" ? t("reauthRequired") : status.status === "error" ? t("requestFailed") : t("signedOut");
|
|
772
772
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
773
773
|
style: embedded ? embeddedPageStyle : pageStyle,
|
|
774
774
|
...embedded ? { "aria-label": t("title") } : { "aria-labelledby": "openai-codex-settings-title" },
|
|
@@ -813,10 +813,10 @@ window.__ModuleLoader__.load({
|
|
|
813
813
|
onClick: () => {
|
|
814
814
|
signIn();
|
|
815
815
|
},
|
|
816
|
-
children: busy ? t("working") : status.status === "error" ? t("loginAgain") : t("login")
|
|
816
|
+
children: busy ? t("working") : status.status === "error" || status.status === "reauth-required" ? t("loginAgain") : t("login")
|
|
817
817
|
})]
|
|
818
818
|
}),
|
|
819
|
-
status.status === "error" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
819
|
+
status.status === "error" || status.status === "reauth-required" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
820
820
|
style: errorStyle,
|
|
821
821
|
children: status.message
|
|
822
822
|
}) : null,
|
|
@@ -938,6 +938,7 @@ window.__ModuleLoader__.load({
|
|
|
938
938
|
signedOut: "Not signed in",
|
|
939
939
|
signingIn: "Waiting for browser authorization…",
|
|
940
940
|
signedIn: "Signed in",
|
|
941
|
+
reauthRequired: "Sign in again",
|
|
941
942
|
login: "Sign in with ChatGPT",
|
|
942
943
|
loginAgain: "Sign in again",
|
|
943
944
|
logout: "Sign out",
|
|
@@ -996,6 +997,7 @@ window.__ModuleLoader__.load({
|
|
|
996
997
|
signedOut: "尚未登录",
|
|
997
998
|
signingIn: "正在等待浏览器授权…",
|
|
998
999
|
signedIn: "已登录",
|
|
1000
|
+
reauthRequired: "需要重新登录",
|
|
999
1001
|
login: "使用 ChatGPT 登录",
|
|
1000
1002
|
loginAgain: "重新登录",
|
|
1001
1003
|
logout: "退出登录",
|
package/lib/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as loginOpenAICodex, C as assertNoOpenAICodexProviderConflict, D as OPENAI_CODEX_USAGE_URL, F as OpenAICodexCredentialStore, I as openAICodexAuthPath, M as openAICodexAuthStatus, N as OPENAI_CODEX_AUTH_FILENAME, O as parseOpenAICodexUsage, P as OPENAI_CODEX_PROVIDER, S as VIEW_IMAGE_TOOL_NAME, T as openAICodexConflictMessage, _ as decodeOpenAICodexSettings, a as name, b as installOpenAICodexSearchEvent, c as OPENAI_CODEX_SEARCH_URL, d as DEFAULT_OPENAI_CODEX_SEARCH_CONTEXT_SIZE, f as DEFAULT_OPENAI_CODEX_SEARCH_MAX_OUTPUT_TOKENS, g as OPENAI_CODEX_SETTINGS_NAMESPACE, h as DEFAULT_OPENAI_CODEX_SETTINGS, i as inject, j as logoutOpenAICodex, k as readOpenAICodexRateLimits, l as OpenAICodexSearchProvider, m as DEFAULT_OPENAI_CODEX_SEARCH_MODEL, n as OPENAI_CODEX_SETTINGS_NS, o as OPENAI_CODEX_BASE_URL, p as DEFAULT_OPENAI_CODEX_SEARCH_MODE, r as apply, s as OPENAI_CODEX_SEARCH_PROVIDER, t as Config, u as mapOpenAICodexSearchResponse, v as resolveOpenAICodexSettings, w as diagnoseOpenAICodex, x as recordOpenAICodexSearchRequest, y as OPENAI_CODEX_SEARCH_MODEL_REQUEST_EVENT } from "./src-KKqkbCFT.js";
|
|
2
2
|
export { Config, 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, OPENAI_CODEX_AUTH_FILENAME, OPENAI_CODEX_BASE_URL, OPENAI_CODEX_PROVIDER, OPENAI_CODEX_SEARCH_MODEL_REQUEST_EVENT, OPENAI_CODEX_SEARCH_PROVIDER, OPENAI_CODEX_SEARCH_URL, OPENAI_CODEX_SETTINGS_NAMESPACE, OPENAI_CODEX_SETTINGS_NS, OPENAI_CODEX_USAGE_URL, OpenAICodexCredentialStore, OpenAICodexSearchProvider, VIEW_IMAGE_TOOL_NAME, apply, assertNoOpenAICodexProviderConflict, decodeOpenAICodexSettings, diagnoseOpenAICodex, inject, installOpenAICodexSearchEvent, loginOpenAICodex, logoutOpenAICodex, mapOpenAICodexSearchResponse, name, openAICodexAuthPath, openAICodexAuthStatus, openAICodexConflictMessage, parseOpenAICodexUsage, readOpenAICodexRateLimits, recordOpenAICodexSearchRequest, resolveOpenAICodexSettings };
|
|
@@ -252,6 +252,27 @@ async function openAICodexAuthStatus(store = new OpenAICodexCredentialStore()) {
|
|
|
252
252
|
/** Fixed endpoint used by the official Codex client for ChatGPT rate limits. */
|
|
253
253
|
const OPENAI_CODEX_USAGE_URL = "https://chatgpt.com/backend-api/wham/usage";
|
|
254
254
|
const USAGE_REQUEST_TIMEOUT_MS = 15e3;
|
|
255
|
+
/** Stable public discriminant for an expired or revoked Codex OAuth session. */
|
|
256
|
+
const OPENAI_CODEX_REAUTH_REQUIRED_CODE = "OPENAI_CODEX_REAUTH_REQUIRED";
|
|
257
|
+
/** Fixed, secret-free message for a browser-facing reauthorization prompt. */
|
|
258
|
+
const OPENAI_CODEX_REAUTH_REQUIRED_MESSAGE = "OpenAI Codex authorization must be renewed";
|
|
259
|
+
/**
|
|
260
|
+
* Raised when the usage endpoint rejects the current OAuth session.
|
|
261
|
+
*
|
|
262
|
+
* The error intentionally carries no response, credential, or account data so
|
|
263
|
+
* callers can safely pass its fixed message across the Web boundary.
|
|
264
|
+
*/
|
|
265
|
+
var OpenAICodexReauthRequiredError = class extends Error {
|
|
266
|
+
code = OPENAI_CODEX_REAUTH_REQUIRED_CODE;
|
|
267
|
+
constructor() {
|
|
268
|
+
super(OPENAI_CODEX_REAUTH_REQUIRED_MESSAGE);
|
|
269
|
+
this.name = "OpenAICodexReauthRequiredError";
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
/** Identify the dedicated reauthorization failure without comparing messages. */
|
|
273
|
+
function isOpenAICodexReauthRequiredError(error) {
|
|
274
|
+
return error instanceof OpenAICodexReauthRequiredError;
|
|
275
|
+
}
|
|
255
276
|
function isRecord$2(value) {
|
|
256
277
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
257
278
|
}
|
|
@@ -363,7 +384,10 @@ async function readOpenAICodexRateLimits(store) {
|
|
|
363
384
|
},
|
|
364
385
|
signal: AbortSignal.timeout(USAGE_REQUEST_TIMEOUT_MS)
|
|
365
386
|
});
|
|
366
|
-
if (!response.ok)
|
|
387
|
+
if (!response.ok) {
|
|
388
|
+
if (response.status === 401 || response.status === 403) throw new OpenAICodexReauthRequiredError();
|
|
389
|
+
throw new Error(`OpenAI Codex usage request failed with HTTP ${response.status}`);
|
|
390
|
+
}
|
|
367
391
|
let value;
|
|
368
392
|
try {
|
|
369
393
|
value = await response.json();
|
|
@@ -507,6 +531,10 @@ var OpenAICodexWebAuth = class {
|
|
|
507
531
|
usage: await readOpenAICodexRateLimits(this.store)
|
|
508
532
|
};
|
|
509
533
|
} catch (error) {
|
|
534
|
+
if (isOpenAICodexReauthRequiredError(error)) return {
|
|
535
|
+
status: "reauth-required",
|
|
536
|
+
message: OPENAI_CODEX_REAUTH_REQUIRED_MESSAGE
|
|
537
|
+
};
|
|
510
538
|
return {
|
|
511
539
|
status: "signed-in",
|
|
512
540
|
usage: { rateLimits: [] },
|
|
@@ -618,7 +646,7 @@ function registerOpenAICodexAuthRoutes(ctx, store) {
|
|
|
618
646
|
}
|
|
619
647
|
//#endregion
|
|
620
648
|
//#region src/version.ts
|
|
621
|
-
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.
|
|
649
|
+
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.6";
|
|
622
650
|
//#endregion
|
|
623
651
|
//#region src/doctor.ts
|
|
624
652
|
/** Secret-free diagnostics and duplicate-provider guidance. */
|
|
@@ -1481,4 +1509,4 @@ function apply(ctx, config) {
|
|
|
1481
1509
|
scheduleCapabilities();
|
|
1482
1510
|
}
|
|
1483
1511
|
//#endregion
|
|
1484
|
-
export {
|
|
1512
|
+
export { loginOpenAICodex as A, assertNoOpenAICodexProviderConflict as C, OPENAI_CODEX_USAGE_URL as D, CODEX_CONNECT_VERSION as E, OpenAICodexCredentialStore as F, openAICodexAuthPath as I, openAICodexAuthStatus as M, OPENAI_CODEX_AUTH_FILENAME as N, parseOpenAICodexUsage as O, OPENAI_CODEX_PROVIDER as P, VIEW_IMAGE_TOOL_NAME as S, openAICodexConflictMessage as T, decodeOpenAICodexSettings as _, name as a, installOpenAICodexSearchEvent as b, OPENAI_CODEX_SEARCH_URL as c, DEFAULT_OPENAI_CODEX_SEARCH_CONTEXT_SIZE as d, DEFAULT_OPENAI_CODEX_SEARCH_MAX_OUTPUT_TOKENS as f, OPENAI_CODEX_SETTINGS_NAMESPACE as g, DEFAULT_OPENAI_CODEX_SETTINGS as h, inject as i, logoutOpenAICodex as j, readOpenAICodexRateLimits as k, OpenAICodexSearchProvider as l, DEFAULT_OPENAI_CODEX_SEARCH_MODEL as m, OPENAI_CODEX_SETTINGS_NS as n, OPENAI_CODEX_BASE_URL as o, DEFAULT_OPENAI_CODEX_SEARCH_MODE as p, apply as r, OPENAI_CODEX_SEARCH_PROVIDER as s, Config as t, mapOpenAICodexSearchResponse as u, resolveOpenAICodexSettings as v, diagnoseOpenAICodex as w, recordOpenAICodexSearchRequest as x, OPENAI_CODEX_SEARCH_MODEL_REQUEST_EVENT as y };
|
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.6",
|
|
6
6
|
"author": "Frank Song",
|
|
7
7
|
"contributors": [
|
|
8
8
|
"Yan-Zero (original dsh-codex author)"
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"test": "vitest run",
|
|
44
44
|
"typecheck": "tsc -p tsconfig.json && tsc -p tsconfig.client.json",
|
|
45
45
|
"pack:check": "node scripts/check-pack.mjs",
|
|
46
|
+
"check:dsh-install": "node scripts/check-dsh-install.mjs",
|
|
46
47
|
"check": "pnpm run lint && pnpm run typecheck && pnpm run test && pnpm run build && pnpm run pack:check",
|
|
47
48
|
"prepublishOnly": "pnpm --config.minimum-release-age=0 run check"
|
|
48
49
|
},
|