dsh-openai-subscription 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -12
- package/README.zh.md +36 -12
- package/dist/client.d.ts +8 -0
- package/dist/client.js +507 -170
- package/dist/driver.d.ts +12 -0
- package/dist/driver.js +136 -0
- package/dist/errors.d.ts +13 -0
- package/dist/errors.js +58 -0
- package/dist/host.d.ts +32 -14
- package/dist/host.js +242 -312
- package/dist/models.js +91 -55
- package/dist/oauth.js +2 -2
- package/dist/platform.d.ts +17 -0
- package/dist/platform.js +279 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -18,15 +18,22 @@ Use a ChatGPT subscription with Codex access in [DeepSeek Harness](https://githu
|
|
|
18
18
|
|
|
19
19
|
- DSH CLI 0.1.2-rc.1 or newer
|
|
20
20
|
- `pnpm` available on `PATH` for plugin installation
|
|
21
|
-
- Node.js 22.19 or newer
|
|
21
|
+
- DSH running under Node.js 22.19 or newer; authorization reuses that process's Node executable instead of a different `node` on `PATH`
|
|
22
22
|
- A [ChatGPT plan with Codex access](https://help.openai.com/en/articles/11369540-use-codex-with-a-chatgpt-plan) and device-code authorization enabled
|
|
23
23
|
- Network access to `auth.openai.com` and `chatgpt.com`
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
### Platforms and deployment
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
| Environment | Implementation and requirements |
|
|
28
|
+
| --- | --- |
|
|
29
|
+
| Linux / macOS | DSH's default Bash executor; no GNU `readlink` or separate `pi` CLI required. |
|
|
30
|
+
| Windows | DSH's default PowerShell executor and Windows Node; installation paths may contain spaces, Unicode, or apostrophes. Custom Bash executors are not part of this default configuration. |
|
|
31
|
+
| WSL / SSH / containers | Execution follows the DSH host's OS. Verification can happen in a browser on another device; no browser-to-host OAuth callback port is needed. |
|
|
32
|
+
| Mobile / remote Web | Use the existing DSH Web settings page. If clipboard access is unavailable, the device code is selected for manual copying. |
|
|
33
|
+
|
|
34
|
+
Discovery prefers the running DSH and its `llm-pi-ai` dependency, following symlinks and pnpm virtual-store dependencies. Fallbacks include npm/nvm, `NODE_PATH`, pnpm, bun, and Windows user installation roots. It never executes a discovered `pi` program.
|
|
35
|
+
|
|
36
|
+
CI is configured for Linux/macOS/Windows × Node.js 22.19/24 × npm/pnpm builds and mocked regression tests; this matrix does not imply real OpenAI sign-in has been validated on every platform. The Web settings entry is not a native TUI/ACP settings interface.
|
|
30
37
|
|
|
31
38
|
## Installation
|
|
32
39
|
|
|
@@ -48,6 +55,14 @@ Restart `dsh web`, then refresh the existing page. DSH registers the plugin auto
|
|
|
48
55
|
|
|
49
56
|
`llm-pi-ai` automatically renews refreshable OAuth credentials during model requests. **Refresh authorization** in this settings page is primarily a manual recovery action.
|
|
50
57
|
|
|
58
|
+
### Status and recovery
|
|
59
|
+
|
|
60
|
+
- Settings distinguish saved authorization, expired or unknown token lifetime, model-sync results, and missing host services. Saved authorization does not guarantee account access or remaining quota.
|
|
61
|
+
- Refreshing/reopening the page or reconnecting Web can recover pending device authorization from the host. Device codes are not stored in browser storage and are removed from host progress snapshots when authorization ends.
|
|
62
|
+
- Polling uses bounded backoff. Repeated failures or the waiting limit expose **Resume status checks** instead of retrying forever or treating an old connection as a successful new authorization. Device authorization waits up to 15 minutes.
|
|
63
|
+
- A sync/disconnect timeout does not prove that the host operation failed. Reload status before deciding whether to retry; the plugin does not automatically repeat mutations or silently cancel sign-in.
|
|
64
|
+
- Host-side locking prevents sign-in, sync, and disconnect from overwriting one another across settings pages. Disconnect remains available after a partial credential save.
|
|
65
|
+
|
|
51
66
|
### Model synchronization rules
|
|
52
67
|
|
|
53
68
|
DSH treats `openai-codex.models` as a complete replacement list, not an additive list. Adding one model manually therefore hides the previous implicit built-in catalog. This plugin writes a complete, owned snapshot instead:
|
|
@@ -80,22 +95,31 @@ Restart the Web profile and refresh the page afterward.
|
|
|
80
95
|
## Troubleshooting
|
|
81
96
|
|
|
82
97
|
- **The settings entry is missing:** confirm the plugin is installed in the `web` profile with `dsh plugin --profile web why dsh-openai-subscription`, then restart DSH and refresh the page.
|
|
83
|
-
- **
|
|
84
|
-
- **
|
|
85
|
-
- **
|
|
86
|
-
- **
|
|
87
|
-
- **
|
|
98
|
+
- **Sign-in cannot start / missing component or service:** check the Node version running DSH and its credential, Shell, and model-adapter services; update or restart DSH. A separate `pi` CLI is not required.
|
|
99
|
+
- **Device authorization disabled (`device-auth-disabled`):** enable it in ChatGPT security settings, then connect again.
|
|
100
|
+
- **Expired authorization (`authorization-expired`):** refresh authorization; if rejected, disconnect and sign in again.
|
|
101
|
+
- **Access denied (`access-denied`):** check Codex/workspace access and DSH execution permissions. HTTP 403 does not necessarily mean an expired token; the plugin never automatically relaxes sandbox permissions.
|
|
102
|
+
- **Network / timeout (`network` / `timeout`):** check DNS, TLS, proxies, and access from the DSH host to `auth.openai.com` and `chatgpt.com`. Browser connectivity does not prove host connectivity.
|
|
103
|
+
- **Rate limited (`rate-limited`):** wait before retrying; do not repeatedly click or loop authorization refreshes.
|
|
104
|
+
- **Models need syncing:** select **Sync models** and review the confirmation. Existing allow-lists are merged only after explicit confirmation.
|
|
105
|
+
- **Invalid or empty model response:** incomplete responses do not replace the existing catalog; retry later or check plan access.
|
|
106
|
+
- **Ownership save failed (`ownership-save-failed`):** the complete model list was written, but its ownership snapshot was not. Fix credential-store writes before syncing again; do not assume the list is unchanged. Cleanup conservatively keeps entries with uncertain ownership.
|
|
107
|
+
- **Credential save or cleanup failed:** fix DSH credential-store permissions and retry; the retained Disconnect action allows cleanup to continue. Never paste tokens or device codes for troubleshooting.
|
|
88
108
|
|
|
89
109
|
## Compatibility notes
|
|
90
110
|
|
|
91
|
-
Dynamic discovery uses the backend endpoint used by the official ChatGPT Codex client, but that endpoint is not a public, stability-guaranteed OpenAI API and may change. It does not provide complete output-limit, cost, or wire-compatibility metadata. `llm-pi-ai` fills metadata for known models; unknown models use adapter defaults. Catalog presence also does not guarantee that
|
|
111
|
+
Dynamic discovery uses the backend endpoint used by the official ChatGPT Codex client, but that endpoint is not a public, stability-guaranteed OpenAI API and may change. It does not provide complete output-limit, cost, or wire-compatibility metadata. `llm-pi-ai` fills metadata for known models; unknown models use adapter defaults. Catalog presence also does not guarantee that the installed adapter supports every new model capability.
|
|
92
112
|
|
|
93
113
|
## Security and privacy
|
|
94
114
|
|
|
95
|
-
Your password is entered only on OpenAI's website; the plugin never receives it. OAuth credentials remain in
|
|
115
|
+
Your password is entered only on OpenAI's website; the plugin never receives it. Verification links are restricted to OpenAI's official device-authorization page. “Local” means the DSH host, not the browser device in a remote deployment. OAuth credentials remain in that host's DSH credential store and travel through subprocess stdin/stdout, not command arguments or environment variables. The settings status API returns semantic facts such as connection, token-lifetime category, refresh capability, and model state—not tokens, internal account IDs, or exact expiry timestamps. Plugin error feedback and logs use safe categories instead of forwarding raw upstream diagnostics. Do not share the temporary device code.
|
|
96
116
|
|
|
97
117
|
OpenAI's terms, privacy policy, model availability, and usage limits still apply. This is an independent community plugin and is not affiliated with or endorsed by OpenAI or DeepSeek.
|
|
98
118
|
|
|
119
|
+
## Development and validation
|
|
120
|
+
|
|
121
|
+
After installing dependencies, run `npm run check` (or `pnpm run check`) for typechecking, build, and regression tests. Use `npm pack --dry-run --ignore-scripts` to inspect published files. Tests mock OAuth, network, and credential services; they do not access real accounts. After editing the plugin, rebuild and reinstall/load that version, restart `dsh web`, and refresh the existing page. Editing source alone does not update the installed GUI plugin.
|
|
122
|
+
|
|
99
123
|
## License
|
|
100
124
|
|
|
101
125
|
MIT — see [LICENSE](LICENSE).
|
package/README.zh.md
CHANGED
|
@@ -18,15 +18,22 @@
|
|
|
18
18
|
|
|
19
19
|
- DSH CLI 0.1.2-rc.1 或更高版本
|
|
20
20
|
- `PATH` 中可用的 `pnpm`,用于安装插件
|
|
21
|
-
-
|
|
21
|
+
- 运行 DSH 的 Node.js 为 22.19 或更高版本;授权复用该进程的 Node 可执行文件,不依赖另一个 `PATH` 中的 `node`
|
|
22
22
|
- [包含 Codex 权限的 ChatGPT 套餐](https://help.openai.com/en/articles/11369540-use-codex-with-a-chatgpt-plan),并已启用设备码授权
|
|
23
23
|
- 能够访问 `auth.openai.com` 和 `chatgpt.com`
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
### 平台与部署方式
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
| 环境 | 实现与要求 |
|
|
28
|
+
| --- | --- |
|
|
29
|
+
| Linux / macOS | 使用 DSH 默认 Bash 执行器;无需 GNU `readlink` 或单独安装 `pi` CLI。 |
|
|
30
|
+
| Windows | 使用 DSH 默认 PowerShell 执行器及 Windows Node;支持包含空格、中文和单引号的安装路径。自定义 Bash 执行器不属于此默认配置。 |
|
|
31
|
+
| WSL / SSH / 容器 | 根据运行 DSH 的主机选择执行器;浏览器可以在另一台设备完成验证,无需浏览器到主机的 OAuth 回调端口。 |
|
|
32
|
+
| 手机 / 远程 Web 页面 | 使用已有 DSH Web 设置页;剪贴板不可用时自动选中设备码以便手动复制。 |
|
|
33
|
+
|
|
34
|
+
组件查找优先使用正在运行的 DSH 及其 `llm-pi-ai` 依赖,识别符号链接和 pnpm 虚拟存储;再检查 npm/nvm、`NODE_PATH`、pnpm、bun 和 Windows 用户安装目录。不会执行 PATH 中找到的 `pi` 程序。
|
|
35
|
+
|
|
36
|
+
CI 已配置 Linux、macOS、Windows × Node.js 22.19/24 × npm/pnpm 的构建与模拟回归测试;矩阵配置不等同于各平台均已完成真实 OpenAI 登录验证。Web 设置入口不代表提供原生 TUI/ACP 设置界面。
|
|
30
37
|
|
|
31
38
|
## 安装
|
|
32
39
|
|
|
@@ -48,6 +55,14 @@ dsh plugin --profile web add dsh-openai-subscription
|
|
|
48
55
|
|
|
49
56
|
`llm-pi-ai` 会在模型请求期间自动续期可刷新的 OAuth 凭证。设置页中的 **刷新授权** 主要用于授权异常时的手动恢复。
|
|
50
57
|
|
|
58
|
+
### 状态与恢复
|
|
59
|
+
|
|
60
|
+
- 设置页区分连接状态、令牌已过期或到期状态未知、模型同步结果,以及缺失的主机服务;“已保存授权”不等于账号一定有权限或额度。
|
|
61
|
+
- 页面刷新、关闭后重开或 Web 连接恢复时,可从主机恢复仍在进行的设备授权。设备码不写入浏览器存储,授权结束即从主机进度快照移除。
|
|
62
|
+
- 轮询采用有界退避;连续失败或达到等待上限后显示“恢复状态检查”,不会无限重试,也不会把旧连接误判为本次授权成功。设备授权最长等待 15 分钟,请及时完成验证。
|
|
63
|
+
- 同步或断开请求超时并不证明主机操作失败。先刷新状态再决定是否重试;插件不会自动重复这些写入操作或暗中取消登录。
|
|
64
|
+
- 登录、同步和断开在主机上互斥,避免多个设置页相互覆盖。授权只保存一部分时仍可使用断开操作清理残留。
|
|
65
|
+
|
|
51
66
|
### 模型同步规则
|
|
52
67
|
|
|
53
68
|
DSH 的 `openai-codex.models` 是完整替代列表,而不是可追加列表;只手动添加一个模型会遮蔽原来的隐式内置目录。此插件因此写入一份完整、可追踪的快照:
|
|
@@ -80,22 +95,31 @@ dsh plugin --profile web remove dsh-openai-subscription
|
|
|
80
95
|
## 故障排查
|
|
81
96
|
|
|
82
97
|
- **设置中没有入口:** 使用 `dsh plugin --profile web why dsh-openai-subscription` 确认插件已安装到 `web` profile,然后重启 DSH 并刷新页面。
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
-
|
|
86
|
-
-
|
|
87
|
-
-
|
|
98
|
+
- **无法开始授权 / 组件或服务不可用:** 检查运行 DSH 的 Node 版本以及凭证、Shell、模型适配器服务;更新或重启 DSH。无需单独安装 `pi` CLI。
|
|
99
|
+
- **设备码授权未启用 (`device-auth-disabled`):** 在 ChatGPT 安全设置启用设备码授权,再连接。
|
|
100
|
+
- **授权过期 (`authorization-expired`):** 刷新授权;若刷新被拒绝,则断开并重新登录。
|
|
101
|
+
- **访问被拒绝 (`access-denied`):** 检查 Codex/工作区权限和 DSH 执行权限;403 不一定代表令牌过期,插件不会自动放宽沙箱权限。
|
|
102
|
+
- **网络 / 超时 (`network` / `timeout`):** 检查 DSH 主机到 `auth.openai.com`、`chatgpt.com` 的 DNS、TLS、代理和网络连接。浏览器能打开网站不代表主机可访问。
|
|
103
|
+
- **请求过于频繁 (`rate-limited`):** 等待后再试;不要反复点击或循环刷新授权。
|
|
104
|
+
- **模型需要同步:** 点击 **同步模型** 并阅读确认提示。只有明确确认后才会合并已有 allow-list。
|
|
105
|
+
- **模型响应无效或为空:** 现有目录不会被不完整响应覆盖;稍后重试或检查套餐权限。
|
|
106
|
+
- **管理记录保存失败 (`ownership-save-failed`):** 完整模型列表已写入,但管理快照未保存;请修复凭证库写入问题后再同步,不要假设列表未更改。清理时会保守保留无法确认归属的条目。
|
|
107
|
+
- **凭证保存或清理失败:** 修复 DSH 凭证库权限后重试;保留的断开按钮可继续清理。请勿粘贴令牌或设备码排错。
|
|
88
108
|
|
|
89
109
|
## 兼容性说明
|
|
90
110
|
|
|
91
|
-
动态目录使用 ChatGPT 官方 Codex 客户端所使用的后端接口,但它不是公开、稳定承诺的 OpenAI API,未来可能变化。接口不提供完整的输出上限、费用或 wire compatibility 元数据;已知模型由 `llm-pi-ai`
|
|
111
|
+
动态目录使用 ChatGPT 官方 Codex 客户端所使用的后端接口,但它不是公开、稳定承诺的 OpenAI API,未来可能变化。接口不提供完整的输出上限、费用或 wire compatibility 元数据;已知模型由 `llm-pi-ai` 补全,未知模型使用适配器默认值。目录中出现模型也不保证当前安装的适配器支持其所有新能力。
|
|
92
112
|
|
|
93
113
|
## 安全与隐私
|
|
94
114
|
|
|
95
|
-
密码只在 OpenAI
|
|
115
|
+
密码只在 OpenAI 官方页面输入,本插件不会接触密码。验证链接仅允许 OpenAI 官方设备授权页面。这里的“本机”指运行 DSH 的主机,远程部署时不是浏览器所在设备。OAuth 凭证保存在该主机的 DSH 凭证库中,通过子进程标准输入/输出传递,不放入命令参数或环境变量。设置页状态接口只返回连接、到期状态分类、可刷新性、模型状态等语义信息,不返回令牌、内部账号 ID 或精确到期时间。插件错误反馈和日志只使用安全的错误分类,不转发上游原始诊断。设备验证码在有效期内属于敏感信息,请勿分享。
|
|
96
116
|
|
|
97
117
|
使用过程仍受 OpenAI 的条款、隐私政策、模型可用性和用量限制约束。本项目是独立的社区插件,与 OpenAI 或 DeepSeek 无隶属或背书关系。
|
|
98
118
|
|
|
119
|
+
## 开发与验证
|
|
120
|
+
|
|
121
|
+
安装依赖后运行 `npm run check`(或 `pnpm run check`),完成类型检查、构建和回归测试;`npm pack --dry-run --ignore-scripts` 检查发布文件。测试使用模拟 OAuth、网络与凭证服务,不访问真实账号。修改插件后需要重新构建并重新安装/加载该版本,再重启 `dsh web`、刷新现有页面;仅修改源码不会更新已安装的 GUI 插件。
|
|
122
|
+
|
|
99
123
|
## 许可证
|
|
100
124
|
|
|
101
125
|
MIT——见 [LICENSE](LICENSE)。
|
package/dist/client.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ interface FlowNotice {
|
|
|
2
2
|
kind?: 'requesting-code' | 'enter-code' | 'refreshing' | 'models-synced' | 'models-sync-failed';
|
|
3
3
|
url?: string;
|
|
4
4
|
code?: string;
|
|
5
|
+
errorCode?: string;
|
|
5
6
|
}
|
|
6
7
|
interface StatusInfo {
|
|
7
8
|
configured: boolean;
|
|
@@ -9,18 +10,25 @@ interface StatusInfo {
|
|
|
9
10
|
refreshable: boolean;
|
|
10
11
|
modelsSynced: boolean;
|
|
11
12
|
modelCount: number;
|
|
13
|
+
unavailableReason?: string;
|
|
14
|
+
credentialState: 'valid' | 'expired' | 'unknown';
|
|
15
|
+
cleanupAvailable: boolean;
|
|
16
|
+
flowPending: boolean;
|
|
12
17
|
}
|
|
13
18
|
interface PollInfo {
|
|
14
19
|
status: 'idle' | 'pending' | 'done';
|
|
15
20
|
notices: FlowNotice[];
|
|
16
21
|
outcome: 'authorized' | 'cancelled' | 'failed' | null;
|
|
22
|
+
errorCode?: string;
|
|
17
23
|
}
|
|
18
24
|
interface AuthorizeInfo {
|
|
19
25
|
started: boolean;
|
|
26
|
+
errorCode?: string;
|
|
20
27
|
}
|
|
21
28
|
interface ModelSyncInfo {
|
|
22
29
|
synced: true;
|
|
23
30
|
count: number;
|
|
31
|
+
warningCode?: string;
|
|
24
32
|
}
|
|
25
33
|
interface RemoteResult<T> {
|
|
26
34
|
ok?: boolean;
|