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 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 available as `node`
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
- Install or update DSH when needed:
25
+ ### Platforms and deployment
26
26
 
27
- ```sh
28
- npm install -g pnpm @deepseek-ai/dsh@next
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
- - **Authorization cannot start:** update DSH, confirm `node --version` meets the requirement, and check access to the OpenAI authentication service.
84
- - **The device code is rejected:** enable device-code authorization in ChatGPT security settings and start a new connection.
85
- - **Models need syncing:** select **Sync models**. If an explicit list already exists, review the confirmation and continue; local edits are preserved.
86
- - **Model sync fails:** existing settings remain unchanged. Check access to `chatgpt.com` and authorization status, then retry; refresh authorization first if needed.
87
- - **Authorization cannot recover:** disconnect and complete device authorization again.
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 an older adapter supports every new model capability, so update DSH first when calls reveal compatibility problems.
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 the local DSH credential store. The settings status API returns only semantic facts such as connection, refresh capability, model-sync state, and model count. It does not return tokens, internal account IDs, or exact token-expiry timestamps. Do not share the temporary device code.
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
- - `node` 命令对应 Node.js 22.19 或更高版本
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
- 如需安装或更新 DSH:
25
+ ### 平台与部署方式
26
26
 
27
- ```sh
28
- npm install -g pnpm @deepseek-ai/dsh@next
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
- - **无法开始授权:** 更新 DSH,确认 `node --version` 满足要求,并检查 OpenAI 登录服务是否可访问。
84
- - **设备码被拒绝:** 在 ChatGPT 安全设置中启用设备码授权,然后重新连接。
85
- - **模型需要同步:** 点击 **同步模型**。若已有显式模型列表,请阅读确认提示后继续;插件会保留本地编辑。
86
- - **模型同步失败:** 现有设置会保持不变。检查 `chatgpt.com` 的网络访问和授权状态,稍后重试;必要时先刷新授权。
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` 补全,未知模型使用适配器默认值。目录中出现模型也不保证旧版适配器支持其所有新能力,遇到调用兼容问题时请先更新 DSH。
111
+ 动态目录使用 ChatGPT 官方 Codex 客户端所使用的后端接口,但它不是公开、稳定承诺的 OpenAI API,未来可能变化。接口不提供完整的输出上限、费用或 wire compatibility 元数据;已知模型由 `llm-pi-ai` 补全,未知模型使用适配器默认值。目录中出现模型也不保证当前安装的适配器支持其所有新能力。
92
112
 
93
113
  ## 安全与隐私
94
114
 
95
- 密码只在 OpenAI 官方页面输入,本插件不会接触密码。OAuth 凭证保存在本机 DSH 凭证库中。设置页状态接口只返回“是否连接、是否可刷新、模型是否同步、模型数量”等语义信息,不返回令牌、内部账号 ID 或精确令牌到期时间。设备验证码在有效期内属于敏感信息,请勿分享。
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;