dsh-coding-subscription-oauth 0.5.0
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/CHANGELOG.md +136 -0
- package/CONTRIBUTING.md +109 -0
- package/INSTALL.md +220 -0
- package/LICENSE +19 -0
- package/NOTICE +11 -0
- package/README.de.md +254 -0
- package/README.es.md +254 -0
- package/README.fr.md +254 -0
- package/README.ja.md +254 -0
- package/README.ko.md +254 -0
- package/README.md +286 -0
- package/README.pt-BR.md +254 -0
- package/README.ru.md +254 -0
- package/README.zh-CN.md +271 -0
- package/cordis.patch.yml +13 -0
- package/docs/00-project-rules.md +195 -0
- package/docs/02-architecture.md +132 -0
- package/docs/02-architecture.zh-CN.md +128 -0
- package/lib/adapter.d.ts +24 -0
- package/lib/adapter.d.ts.map +1 -0
- package/lib/alias-adapter.d.ts +43 -0
- package/lib/alias-adapter.d.ts.map +1 -0
- package/lib/auth-routes.d.ts +155 -0
- package/lib/auth-routes.d.ts.map +1 -0
- package/lib/auth.d.ts +29 -0
- package/lib/auth.d.ts.map +1 -0
- package/lib/bin.d.ts +6 -0
- package/lib/bin.d.ts.map +1 -0
- package/lib/bin.js +27591 -0
- package/lib/bin.js.map +7 -0
- package/lib/capability-routes.d.ts +43 -0
- package/lib/capability-routes.d.ts.map +1 -0
- package/lib/capability-runtime.d.ts +56 -0
- package/lib/capability-runtime.d.ts.map +1 -0
- package/lib/capability-settings.d.ts +263 -0
- package/lib/capability-settings.d.ts.map +1 -0
- package/lib/capability-tools.d.ts +50 -0
- package/lib/capability-tools.d.ts.map +1 -0
- package/lib/catalog.d.ts +53 -0
- package/lib/catalog.d.ts.map +1 -0
- package/lib/client.js +3 -0
- package/lib/client.js.map +7 -0
- package/lib/codex-http.d.ts +77 -0
- package/lib/codex-http.d.ts.map +1 -0
- package/lib/codex-images.d.ts +109 -0
- package/lib/codex-images.d.ts.map +1 -0
- package/lib/codex-model-capabilities.d.ts +112 -0
- package/lib/codex-model-capabilities.d.ts.map +1 -0
- package/lib/codex-search.d.ts +96 -0
- package/lib/codex-search.d.ts.map +1 -0
- package/lib/codex-usage.d.ts +79 -0
- package/lib/codex-usage.d.ts.map +1 -0
- package/lib/gateway-anthropic-messages.d.ts +8 -0
- package/lib/gateway-anthropic-messages.d.ts.map +1 -0
- package/lib/gateway-auth.d.ts +22 -0
- package/lib/gateway-auth.d.ts.map +1 -0
- package/lib/gateway-backend.d.ts +62 -0
- package/lib/gateway-backend.d.ts.map +1 -0
- package/lib/gateway-body.d.ts +9 -0
- package/lib/gateway-body.d.ts.map +1 -0
- package/lib/gateway-config.d.ts +24 -0
- package/lib/gateway-config.d.ts.map +1 -0
- package/lib/gateway-http.d.ts +16 -0
- package/lib/gateway-http.d.ts.map +1 -0
- package/lib/gateway-openai-chat.d.ts +8 -0
- package/lib/gateway-openai-chat.d.ts.map +1 -0
- package/lib/gateway-openai-responses.d.ts +8 -0
- package/lib/gateway-openai-responses.d.ts.map +1 -0
- package/lib/gateway-parse.d.ts +10 -0
- package/lib/gateway-parse.d.ts.map +1 -0
- package/lib/gateway-protocol.d.ts +47 -0
- package/lib/gateway-protocol.d.ts.map +1 -0
- package/lib/gateway-routes.d.ts +21 -0
- package/lib/gateway-routes.d.ts.map +1 -0
- package/lib/gateway.d.ts +48 -0
- package/lib/gateway.d.ts.map +1 -0
- package/lib/grok-imagine.d.ts +271 -0
- package/lib/grok-imagine.d.ts.map +1 -0
- package/lib/grok-import.d.ts +21 -0
- package/lib/grok-import.d.ts.map +1 -0
- package/lib/http-json.d.ts +10 -0
- package/lib/http-json.d.ts.map +1 -0
- package/lib/ids.d.ts +33 -0
- package/lib/ids.d.ts.map +1 -0
- package/lib/imagine-routes.d.ts +59 -0
- package/lib/imagine-routes.d.ts.map +1 -0
- package/lib/index.d.ts +69 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +35355 -0
- package/lib/index.js.map +7 -0
- package/lib/invariant.d.ts +9 -0
- package/lib/invariant.d.ts.map +1 -0
- package/lib/invariant.js +14 -0
- package/lib/invariant.js.map +7 -0
- package/lib/kimi-errors.d.ts +13 -0
- package/lib/kimi-errors.d.ts.map +1 -0
- package/lib/media-store.d.ts +130 -0
- package/lib/media-store.d.ts.map +1 -0
- package/lib/oauth-import-routes.d.ts +52 -0
- package/lib/oauth-import-routes.d.ts.map +1 -0
- package/lib/oauth-providers.d.ts +26 -0
- package/lib/oauth-providers.d.ts.map +1 -0
- package/lib/oauth-session.d.ts +40 -0
- package/lib/oauth-session.d.ts.map +1 -0
- package/lib/oauth-sources.d.ts +205 -0
- package/lib/oauth-sources.d.ts.map +1 -0
- package/lib/oauth.d.ts +79 -0
- package/lib/oauth.d.ts.map +1 -0
- package/lib/provider.d.ts +38 -0
- package/lib/provider.d.ts.map +1 -0
- package/lib/proxy.d.ts +17 -0
- package/lib/proxy.d.ts.map +1 -0
- package/lib/redact.d.ts +5 -0
- package/lib/redact.d.ts.map +1 -0
- package/lib/session.d.ts +40 -0
- package/lib/session.d.ts.map +1 -0
- package/lib/store.d.ts +46 -0
- package/lib/store.d.ts.map +1 -0
- package/lib/web-origin.d.ts +10 -0
- package/lib/web-origin.d.ts.map +1 -0
- package/lib/web-routes.d.ts +20 -0
- package/lib/web-routes.d.ts.map +1 -0
- package/package.json +185 -0
- package/patches/dsh-agy@0.1.2.patch +25 -0
- package/scripts/release.mjs +166 -0
- package/scripts/smoke-deployed-routes.mjs +146 -0
- package/scripts/verify-deployed-catalog.mjs +87 -0
- package/src/adapter.ts +282 -0
- package/src/alias-adapter.ts +152 -0
- package/src/auth-routes.ts +871 -0
- package/src/auth.ts +67 -0
- package/src/bin.ts +350 -0
- package/src/capability-routes.ts +275 -0
- package/src/capability-runtime.ts +313 -0
- package/src/capability-settings.ts +657 -0
- package/src/capability-tools.ts +666 -0
- package/src/catalog.ts +271 -0
- package/src/client/GrokBuildSettings.tsx +2221 -0
- package/src/client/index.tsx +37 -0
- package/src/client/locales.ts +421 -0
- package/src/codex-http.ts +447 -0
- package/src/codex-images.ts +485 -0
- package/src/codex-model-capabilities.ts +320 -0
- package/src/codex-search.ts +245 -0
- package/src/codex-usage.ts +263 -0
- package/src/gateway-anthropic-messages.ts +84 -0
- package/src/gateway-auth.ts +100 -0
- package/src/gateway-backend.ts +274 -0
- package/src/gateway-body.ts +49 -0
- package/src/gateway-config.ts +76 -0
- package/src/gateway-http.ts +104 -0
- package/src/gateway-openai-chat.ts +124 -0
- package/src/gateway-openai-responses.ts +53 -0
- package/src/gateway-parse.ts +224 -0
- package/src/gateway-protocol.ts +52 -0
- package/src/gateway-routes.ts +152 -0
- package/src/gateway.ts +242 -0
- package/src/grok-imagine.ts +1627 -0
- package/src/grok-import.ts +151 -0
- package/src/http-json.ts +82 -0
- package/src/ids.ts +45 -0
- package/src/imagine-routes.ts +461 -0
- package/src/index.ts +598 -0
- package/src/invariant.ts +17 -0
- package/src/kimi-errors.ts +26 -0
- package/src/media-store.ts +927 -0
- package/src/oauth-import-routes.ts +314 -0
- package/src/oauth-providers.ts +152 -0
- package/src/oauth-session.ts +183 -0
- package/src/oauth-sources.ts +1104 -0
- package/src/oauth.ts +620 -0
- package/src/provider.ts +128 -0
- package/src/proxy.ts +99 -0
- package/src/redact.ts +72 -0
- package/src/session.ts +218 -0
- package/src/store.ts +217 -0
- package/src/web-origin.ts +60 -0
- package/src/web-routes.ts +75 -0
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
|
|
2
|
+
<!-- banner -->
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+
# 🔐 dsh-coding-subscription-oauth
|
|
6
|
+
|
|
7
|
+
**v0.5.0** · 原名 `dsh-grok-build`
|
|
8
|
+
|
|
9
|
+
**面向 [DeepSeek Harness](https://github.com/deepseek-ai/dsh) 的编码订阅 OAuth 插件。** 把 SuperGrok / X Premium(Grok Build)、ChatGPT Plus/Pro(Codex)、Kimi Code、Claude Pro/Max 和 Google Antigravity 接到 DSH——不必再开一份按量 API-key,**也不要把 token 粘贴进聊天。**
|
|
10
|
+
|
|
11
|
+
[](LICENSE)
|
|
12
|
+
[](CONTRIBUTING.md)
|
|
13
|
+
|
|
14
|
+
*[English](README.md) · [中文版](README.zh-CN.md) · [日本語](README.ja.md) · [한국어](README.ko.md) · [Português (BR)](README.pt-BR.md) · [Español](README.es.md) · [Français](README.fr.md) · [Deutsch](README.de.md) · [Русский](README.ru.md)*
|
|
15
|
+
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 项目更名
|
|
21
|
+
|
|
22
|
+
最初只做 Grok Build,仓库名是 **`dsh-grok-build`**。现在覆盖 SuperGrok / Grok Build、ChatGPT Plus Codex、Kimi Code、Claude Code 和 Google Antigravity,因此改为现名。
|
|
23
|
+
|
|
24
|
+
| | 请用这个 | 仍然可用 |
|
|
25
|
+
|---|---|---|
|
|
26
|
+
| GitHub / `dsh plugin add` | [`dsh-coding-subscription-oauth`](https://github.com/lninghaha/dsh-coding-subscription-oauth) | `github:lninghaha/dsh-grok-build`(同一条 `main`) |
|
|
27
|
+
| npm | 当前版本是 `0.5.0`:`dsh plugin --profile web add dsh-coding-subscription-oauth@0.5.0`,之后 `dsh plugin --profile web update dsh-coding-subscription-oauth`。GitHub 安装仍然可用。 | 没有发布过旧 npm 包 |
|
|
28
|
+
| CLI | `dsh-coding-oauth` | `dsh-grok-build` |
|
|
29
|
+
| Cordis 插件 id | `llm-grok-build-oauth` | 不变 |
|
|
30
|
+
| 设置页 HTTP API | `/plugins/dsh-grok-build/*` | 不变 |
|
|
31
|
+
| 凭据文件 | `$DSH_HOME/.grok-build-auth.json` 及其他 `*-oauth-auth.json` | 不变 |
|
|
32
|
+
|
|
33
|
+
## ✨ 特性
|
|
34
|
+
|
|
35
|
+
- 🧾 **自带订阅** —— SuperGrok、ChatGPT Plus/Pro、Kimi Code、Claude Pro/Max,不必另开按量 API-key。
|
|
36
|
+
- 🔑 **本地 OAuth,不用贴 key** —— 在设置页或 CLI 完成授权;access/refresh token 不进聊天、日志和 HTTP 状态。
|
|
37
|
+
- 🧩 **一个插件,五大供应商** —— Grok Build(`cli-chat-proxy.grok.com`)、Codex、Kimi Code、Claude Code 与 Google Antigravity。
|
|
38
|
+
- 🛡️ **安全设计** —— 凭据文件均为 owner-only `0600`、原子写、跨进程文件锁。
|
|
39
|
+
- ⚙️ **动态目录** —— 选择器只列出已登录路由并标注 `(OAuth)`,含 grok-4.6 的 `xhigh`。
|
|
40
|
+
- 🌐 **代理感知** —— 只代理审核过的订阅域名;Kimi 中国流量默认直连。
|
|
41
|
+
- 📥 **手动 CLI 拉取** —— 设置页只读发现白名单内的官方 Grok/Codex/Kimi/Claude CLI OAuth 文件;预览并确认覆盖后,单向拉取一份副本。
|
|
42
|
+
- 🎛️ **可选能力默认关闭** —— Codex 搜索、用量/配额、图像生成/编辑、Fast、Grok Imagine 打开后立即生效。
|
|
43
|
+
- 🔌 **可选本地 API 网关** —— 默认关闭的 loopback OpenAI/Anthropic 兼容服务,只给你自己的工具用,不是公网中继。
|
|
44
|
+
|
|
45
|
+
## 本插件解决的接入问题
|
|
46
|
+
|
|
47
|
+
下面这些搜索词和 DSH 报错,通常就是会搜到这个仓库的原因。
|
|
48
|
+
|
|
49
|
+
| 你搜到 / 看到的 | 实际坏在哪 | 本插件怎么处理 |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| SuperGrok / X Premium 接入 DSH、「Grok Build 和 `api.x.ai` 不是一路」 | 内置 `xai` 路由是**按量 API**。编码订阅走 `cli-chat-proxy.grok.com` | 独立 `grok-build` 路由 + 官方 CLI 指纹头(`X-XAI-Token-Auth`、`x-grok-client-identifier`、`x-grok-client-version`),避免静默 403 |
|
|
52
|
+
| `本轮运行失败` **API key is invalid** / `AUTH` | GUI 把所有 `AUTH` 都显示成这句。常见原因是 OAuth access token 到期(Kimi 约 15 分钟) | 过期前 **5 分钟**主动刷新;遇到 401 先作废本地 token,刷新后再**重试该 step** |
|
|
53
|
+
| 第二轮 Codex / Kimi 报 `INVALID_REPLAY_STATE` | replay state 仍带着 pi-ai 原生 provider id | 保持 Harness route id,并修复历史被污染的 replay |
|
|
54
|
+
| grok-4.6 没有 **xhigh** / Extra High Effort | 线上 `GET /v1/models-v2` 已返回含 `xhigh` 的 `reasoning_efforts`;套用 grok-4.5 模板会被 pi-ai 藏掉 | 解析 live `reasoning_efforts`。4.6 有 `xhigh`,4.5 仍是 low/medium/high |
|
|
55
|
+
| Kimi Code 401,或请求变成 Anthropic `x-api-key` | OAuth token 被当成 Anthropic key 发出 | `api.kimi.com/coding` **只**走 `Authorization: Bearer` |
|
|
56
|
+
| 没登录的 Grok / Codex / Claude 仍出现在模型选择器 | 所有已注册路由都被列出来 | 未认证路由模型列表为空;已登录名称带 `(OAuth)` |
|
|
57
|
+
| **远程 / 无头** DSH 没法浏览器登录 | PKCE 回不到本机 `localhost` | Grok/Codex/Kimi 走设备码;Claude 可粘贴完整 localhost 回调 URL |
|
|
58
|
+
| 开了代理 Grok 通了、国内 Kimi 挂了 | 全局 `HTTPS_PROXY` 一刀切 | 白名单代理;Kimi 默认**直连**(`proxyKimi: true` 才走代理)。`auth.kimi.com` ≠ `api.moonshot.cn` |
|
|
59
|
+
| 想在 DSH 用 ChatGPT Plus / Claude Pro,又不想再买 API | 另开 OpenAI / Anthropic API-key | `codex-oauth` / `claude-code-oauth` 本地 OAuth,与现有 `openai` / `kimi-coding` API-key 路由共存 |
|
|
60
|
+
|
|
61
|
+
## 支持的供应商
|
|
62
|
+
|
|
63
|
+
| 供应商 | 路由 | 认证 | 与现有 API-key 路由共存 |
|
|
64
|
+
|---|---|---|---|
|
|
65
|
+
| **xAI Grok Build** | `grok-build` | SuperGrok / X Premium OAuth | `xai` |
|
|
66
|
+
| **OpenAI Codex** | `codex-oauth` · 可选 `codex-oauth-fast` | ChatGPT Plus/Pro OAuth | `openai` |
|
|
67
|
+
| **Kimi Code** | `kimi-code-oauth` | Kimi Code OAuth | `kimi-coding` |
|
|
68
|
+
| **Claude Code** | `claude-code-oauth` | Claude Pro/Max OAuth | — |
|
|
69
|
+
| **Google Antigravity** | `agy` | `dsh-agy` Google OAuth | — |
|
|
70
|
+
|
|
71
|
+
> Grok Build 的 device 登录、动态 `/v1/models-v2` 目录与 Responses 流式推理已在实机上验证。Codex/Kimi/Claude 复用 `@earendil-works/pi-ai` 的 provider-native OAuth/刷新协议,不重新实现各供应商流程。
|
|
72
|
+
|
|
73
|
+
## 🚀 快速开始
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# 1. 安装到 web profile
|
|
77
|
+
dsh plugin --profile web add github:lninghaha/dsh-coding-subscription-oauth
|
|
78
|
+
|
|
79
|
+
# 2. 可选 —— Google Antigravity(固定审核过的版本)
|
|
80
|
+
dsh plugin --profile web add dsh-agy@0.1.2
|
|
81
|
+
|
|
82
|
+
# 3. 重启常驻的 dsh web 服务
|
|
83
|
+
systemctl --user restart dsh-web.service
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
然后打开 **设置 → 编码 OAuth** 登录任一供应商即可。选择器会自动列出已认证的模型。
|
|
87
|
+
|
|
88
|
+
## 📚 目录
|
|
89
|
+
|
|
90
|
+
- [项目更名](#项目更名)
|
|
91
|
+
- [本插件解决的接入问题](#本插件解决的接入问题)
|
|
92
|
+
- [安装](#安装)
|
|
93
|
+
- [设置页](#设置页)
|
|
94
|
+
- [可选能力](#可选能力)
|
|
95
|
+
- [CLI](#cli)
|
|
96
|
+
- [Kimi 中国说明](#kimi-中国说明)
|
|
97
|
+
- [网络代理](#网络代理)
|
|
98
|
+
- [弹性重试](#弹性重试)
|
|
99
|
+
- [凭据](#凭据)
|
|
100
|
+
- [架构](#架构)
|
|
101
|
+
- [技术方案](#技术方案)
|
|
102
|
+
- [合规](#合规)
|
|
103
|
+
- [文档](#文档)
|
|
104
|
+
- [贡献](#贡献)
|
|
105
|
+
- [许可证](#许可证)
|
|
106
|
+
|
|
107
|
+
## 安装
|
|
108
|
+
|
|
109
|
+
需要 DeepSeek Harness `0.1.0-rc.6+` 与 Node.js 22.19+。完整细节见[安装说明](INSTALL.md)。
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# 从 GitHub
|
|
113
|
+
dsh plugin --profile web add github:lninghaha/dsh-coding-subscription-oauth
|
|
114
|
+
|
|
115
|
+
# 或本地开发目录
|
|
116
|
+
dsh plugin --profile web add ./dsh-coding-subscription-oauth
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
安装后重启 `dsh web`。对实际部署的验证:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
pnpm run verify:deployed # 核对真实 /api/llm.models 与 OAuth 状态
|
|
123
|
+
DSH_EXPECT_AGY_AUTH=signed-in pnpm run verify:deployed # 已登录 Google 时
|
|
124
|
+
|
|
125
|
+
DSH_RESTORE_PROVIDER=openai \
|
|
126
|
+
DSH_RESTORE_MODEL=gpt-5.6-sol \
|
|
127
|
+
DSH_RESTORE_REASONING=max \
|
|
128
|
+
pnpm run smoke:deployed # 真实 Codex/Kimi tool-call + 第二个用户 turn 回放
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
> `smoke:deployed` 会创建临时会话、分别测试 Codex/Kimi 工具调用与第二个用户 turn(覆盖 `INVALID_REPLAY_STATE` 回归),恢复显式指定的默认模型后归档测试会话。
|
|
132
|
+
|
|
133
|
+
## 设置页
|
|
134
|
+
|
|
135
|
+
打开 **设置 → 编码 OAuth**:
|
|
136
|
+
|
|
137
|
+
| 供应商 | 方式 |
|
|
138
|
+
|---|---|
|
|
139
|
+
| Grok | 授权码 · 设备码 · 模型勾选 |
|
|
140
|
+
| Codex | 设备码(推荐远程 DSH)· 浏览器 PKCE |
|
|
141
|
+
| Kimi | 设备码 |
|
|
142
|
+
| Claude | 浏览器 PKCE(远程浏览器可粘贴完整 localhost redirect URL) |
|
|
143
|
+
| Antigravity | `dsh-agy` 安装状态 + profile-local CLI 命令 |
|
|
144
|
+
|
|
145
|
+
DSH 主机在远端时优先使用设备码。浏览器/PKCE 登录会打开供应商页面;如果 localhost 回调无法到达这台 DSH 主机,可把返回的授权 code 或完整 redirect URL 粘贴到等待中的设置卡片。
|
|
146
|
+
|
|
147
|
+
设置页还会**只读发现**白名单内的官方 Grok / Codex / Kimi / Claude CLI OAuth 文件。同步是显式的单向**拉取**,不是自动导入:发现 → 预览 → 冲突/指纹核对 → 确认覆盖。官方 CLI 文件从不被写入。读取会拒绝符号链接、非普通文件、非属主文件、组/其他人可读,以及超大文档(`O_NOFOLLOW`)。预览票据一次性、五分钟过期、最多 32 张。
|
|
148
|
+
|
|
149
|
+
选择器只列出已认证的路由;未登录供应商返回空列表。供应商名称统一带 `(OAuth)`,登录或登出后通过 `llm/adapters-updated` 刷新目录。
|
|
150
|
+
|
|
151
|
+
## 可选能力
|
|
152
|
+
|
|
153
|
+
七项开关默认全部**关闭**,打开后**立即生效**(无需重启):`codexSearch`、`codexImages`、`codexImageEdits`、`codexUsage`、`codexFast`、`grokImagineImage`、`grokImagineVideo`。数值控制为 `searchResults`(1–20,默认 5)、`imageCount`(1–4,默认 1)、`videoArtifactTtlMs`(1 小时–7 天,默认 7 天;界面以 1–168 小时显示)。降低视频保留时间会立即缩短并清理已有产物;提高只影响之后生成的产物。管理员也可在插件配置的 `capabilities` 下提供不含秘密的 composition 默认值;`coding-subscription-oauth` 设置区中的用户值会覆盖这层 base,省略时所有开关仍保持关闭。
|
|
154
|
+
|
|
155
|
+
`codex-oauth-fast` 仅在**最新一次 live catalog** 标明至少有一个 `priority` 可用模型后才会出现。请求会发送 `service_tier: priority` 和路由提示。界面写的是 **已请求 Fast**,不保证延迟,也不保证上游会兑现。
|
|
156
|
+
|
|
157
|
+
Codex 搜索、用量和图像是**需显式打开**的私有 `chatgpt.com/backend-api` 端点。图像生成固定使用 `gpt-image-2`。图像编辑只接受当前会话顶层、且由本会话持有的附件 id。
|
|
158
|
+
|
|
159
|
+
Grok Imagine 只走官方 `https://api.x.ai`,模型为 `grok-imagine-image-2.0` 与 `grok-imagine-video-1.5`。凭据是独立的 DSH 凭据引用 `XAI_API_KEY`——不用 Grok OAuth,也不回退到进程环境变量。生成结果在 MIME / 大小 / 超时 / 重定向 / DNS 控制下,仅从冻结主机 `imgen.x.ai`、`videogen.x.ai`、`vidgen.x.ai` 下载,存入私有产物库(单件与唯一对象总量均硬限 256 MiB,最长七天),并只通过同源 loopback 路由提供。
|
|
160
|
+
|
|
161
|
+
## CLI
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
# `dsh-grok-build` 仍是同一命令的别名
|
|
165
|
+
dsh-coding-oauth login [--pkce] | import | status | logout
|
|
166
|
+
|
|
167
|
+
# 新供应商
|
|
168
|
+
dsh-coding-oauth login codex --device-auth | codex --browser | kimi | claude
|
|
169
|
+
dsh-coding-oauth status all
|
|
170
|
+
dsh-coding-oauth logout codex
|
|
171
|
+
|
|
172
|
+
# Antigravity(先安装到 web profile)
|
|
173
|
+
dsh plugin --profile web exec dsh-agy login --headless
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
> `dsh-agy` CLI 在 DSH 进程外修改账号池,无法发送进程内 catalog event——登录或登出后关闭并重新打开模型选择器即可。
|
|
177
|
+
|
|
178
|
+
## Kimi 中国说明
|
|
179
|
+
|
|
180
|
+
Kimi Code 订阅 OAuth 使用 `https://auth.kimi.com`;推理使用 `https://api.kimi.com/coding`。`https://api.moonshot.cn/v1` 是按量付费的 **Moonshot Open Platform** API-key 通道——不存在可切换的“中国 OAuth endpoint”。本插件使用独立的 `kimi-code-oauth` 路由,不影响已有 `kimi-coding` API-key 配置。
|
|
181
|
+
|
|
182
|
+
## 网络代理
|
|
183
|
+
|
|
184
|
+
优先级:`config.proxy` → `CODING_OAUTH_PROXY` → `GROK_BUILD_PROXY` → `HTTPS_PROXY`/`HTTP_PROXY`。
|
|
185
|
+
|
|
186
|
+
```yaml
|
|
187
|
+
- id: llm-grok-build-oauth
|
|
188
|
+
config:
|
|
189
|
+
proxy: http://127.0.0.1:7890
|
|
190
|
+
proxyKimi: false
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
插件只代理审核过的订阅域名(xAI/Grok、OpenAI Codex、Claude/Anthropic、Google Antigravity);其余 DSH 流量保持原 dispatcher。Kimi 默认直连,仅当 `proxyKimi: true` 时才进入代理。
|
|
194
|
+
|
|
195
|
+
## 弹性重试
|
|
196
|
+
|
|
197
|
+
OAuth access token 会在本地记录过期时间前 **5 分钟**主动刷新(pi-ai 0.84+),避免请求踩到令牌寿命的最后几秒。若服务端仍以 401/403 拒绝一个本地尚未过期的令牌(服务端提前吊销或时钟偏差),插件会把凭据的 `expires` 回写到过去,重试的 step 会先刷新再发请求——用户无感知自愈,而不是本轮直接失败。
|
|
198
|
+
|
|
199
|
+
请求重试走 harness 的 retry 策略:瞬时故障(`RATE_LIMIT`/`SERVER`/`TIMEOUT`/`TRANSPORT`/`EMPTY_RESPONSE`)**以及 `AUTH`** 会按指数退避重试(默认 2 次,500 ms → 10 s,10% jitter)。配额耗尽和 refresh token 失效**不**重试——会立刻给出真实错误和重新登录提示。部署级覆盖:
|
|
200
|
+
|
|
201
|
+
```yaml
|
|
202
|
+
- id: llm-grok-build-oauth
|
|
203
|
+
config:
|
|
204
|
+
retryPolicy:
|
|
205
|
+
mode: normal
|
|
206
|
+
maxRetries: 2
|
|
207
|
+
retryableCodes: [EMPTY_RESPONSE, RATE_LIMIT, SERVER, TIMEOUT, TRANSPORT, AUTH]
|
|
208
|
+
backoff: { initialDelayMs: 500, maxDelayMs: 10000, jitterRatio: 0.1 }
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## 凭据
|
|
212
|
+
|
|
213
|
+
owner-only `0600`、原子写、跨进程文件锁:
|
|
214
|
+
|
|
215
|
+
- `$DSH_HOME/.grok-build-auth.json`
|
|
216
|
+
- `$DSH_HOME/.codex-oauth-auth.json`
|
|
217
|
+
- `$DSH_HOME/.kimi-code-oauth-auth.json`
|
|
218
|
+
- `$DSH_HOME/.claude-code-oauth-auth.json`
|
|
219
|
+
|
|
220
|
+
勾选/目录缓存使用对应的 `*-models.json` 文件。Grok Imagine 使用独立的 DSH 凭据名 `XAI_API_KEY`(不是 Grok OAuth 文件)。**任何 HTTP 状态、日志或 UI 都不得返回 token。**
|
|
221
|
+
|
|
222
|
+
## 架构
|
|
223
|
+
|
|
224
|
+
```mermaid
|
|
225
|
+
flowchart LR
|
|
226
|
+
subgraph DSH["DSH Harness"]
|
|
227
|
+
UI[设置 / Web · 编码 OAuth] --> LLM[llm route]
|
|
228
|
+
LLM --> ALIA[路由别名适配器]
|
|
229
|
+
end
|
|
230
|
+
ALIA --> PI[pi-ai 原生 provider<br/>OAuth · 刷新 · 流式]
|
|
231
|
+
PI --> GROK[Grok Build]
|
|
232
|
+
PI --> COD[Codex]
|
|
233
|
+
PI --> KIMI[Kimi]
|
|
234
|
+
PI --> CLAU[Claude]
|
|
235
|
+
AGY[dsh-agy 插件] --> GAL[Google Antigravity]
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## 技术方案
|
|
239
|
+
|
|
240
|
+
- **Grok Build**:`cli-chat-proxy.grok.com/v1` 的 Responses API(不是 `api.x.ai`)、CLI 指纹头、live `/v1/models-v2`(含 grok-4.6 的 `reasoning.effort: xhigh`)。
|
|
241
|
+
- **Codex/Kimi/Claude**:pi-ai 原生 provider 负责 OAuth 与刷新;路由别名适配器映射到原生 id,避免多轮 `INVALID_REPLAY_STATE`。
|
|
242
|
+
- Kimi access token 显式转为 `Authorization: Bearer`——绝不会误发成 Anthropic `x-api-key`。
|
|
243
|
+
- **Codex Fast / 私有端点**:`codex-oauth-fast` 需显式打开,目录过期则失败关闭;搜索、用量和 `gpt-image-2` 图像默认关闭。
|
|
244
|
+
- **Grok Imagine**:只走官方 `api.x.ai`,`XAI_API_KEY` 通过 DSH 凭据解析,下载路由为同源 `/plugins/dsh-grok-build/imagine/*`。
|
|
245
|
+
- Google Antigravity **不**在本项目逆向,使用固定版本的专用 DSH 插件。
|
|
246
|
+
|
|
247
|
+
## 合规
|
|
248
|
+
|
|
249
|
+
通过第三方 harness 使用编码订阅可能处于各供应商服务条款灰色地带,并可能触发配额、地区或账号风控。**仅使用自己的账号**;本项目不支持批量账号、额度转售、远程 relay、付费墙绕过或客户端伪装。商用优先选择官方 API-key 通道。
|
|
250
|
+
|
|
251
|
+
## 文档
|
|
252
|
+
|
|
253
|
+
| 文档 | 用途 |
|
|
254
|
+
|---|---|
|
|
255
|
+
| [`INSTALL.md`](INSTALL.md) | 安装与使用细节 |
|
|
256
|
+
| [`CHANGELOG.md`](CHANGELOG.md) | 版本历史 |
|
|
257
|
+
| [`docs/00-project-rules.md`](docs/00-project-rules.md) | 版本、发版循环、公开层与本地内参分层 |
|
|
258
|
+
| [`docs/02-architecture.md`](docs/02-architecture.md) | 内部架构(路由、数据流、模块、API)· [中文](docs/02-architecture.zh-CN.md) |
|
|
259
|
+
| [`CONTRIBUTING.md`](CONTRIBUTING.md) | 贡献指南 |
|
|
260
|
+
|
|
261
|
+
## 相关项目
|
|
262
|
+
|
|
263
|
+
- [`dsh-agy`](https://www.npmjs.com/package/dsh-agy) —— 用于 Google Antigravity 的独立固定版本插件。
|
|
264
|
+
|
|
265
|
+
## 贡献
|
|
266
|
+
|
|
267
|
+
欢迎各类贡献——功能、文档、翻译、Bug 反馈。流程、提交规范与发版循环见 **[CONTRIBUTING](CONTRIBUTING.md)**。若你的语言不在列表中,欢迎 PR 一份 README 翻译,我们会加入上方语言表。
|
|
268
|
+
|
|
269
|
+
## 许可证
|
|
270
|
+
|
|
271
|
+
[Apache-2.0](LICENSE) · 参见 [NOTICE](NOTICE)。部分代码派生自 [dsh-xai](https://github.com/MirDie/dsh-xai) 项目(Apache-2.0)。
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Optional coding-subscription routes over the base composition. Grok Build
|
|
2
|
+
# remains the bundle fallback for backward compatibility; a saved
|
|
3
|
+
# agent-default-model setting still wins over this value.
|
|
4
|
+
|
|
5
|
+
- id: agent-default-model
|
|
6
|
+
config:
|
|
7
|
+
provider: grok-build
|
|
8
|
+
model: grok-4.6
|
|
9
|
+
|
|
10
|
+
- insert:
|
|
11
|
+
# `id` is the stable Cordis plugin identifier; `name` is the bundle/package display name.
|
|
12
|
+
- id: llm-grok-build-oauth
|
|
13
|
+
name: dsh-coding-subscription-oauth
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# 00 · Project Rules: Versions, Releases & Maintenance
|
|
2
|
+
|
|
3
|
+
> Applies to the `dsh-coding-subscription-oauth` open-source plugin repository (formerly `dsh-grok-build`).
|
|
4
|
+
> This file is the single source of truth for the repo's conventions and governs `README` and the release flow.
|
|
5
|
+
> Principle: **publish like any general open source project, and never leak development privacy.** Anything facing external users must be public, generic and durable; anything internal (accounts, hosts, tokens, paths, credentials) stays local and must never reach git or the npm artifact.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 0. Open-Source Principles
|
|
10
|
+
|
|
11
|
+
### 0.1 Why we open source
|
|
12
|
+
|
|
13
|
+
This project is published open source so that others can use, study, fork and improve the coding-subscription OAuth integration for DeepSeek Harness — the same way its upstream (`dsh-xai`) was shared with us. Openness is a goal, not an accident of hosting.
|
|
14
|
+
|
|
15
|
+
### 0.2 License & attribution
|
|
16
|
+
|
|
17
|
+
- The project is **Apache-2.0**. Every contribution is licensed under the same terms (see `LICENSE`).
|
|
18
|
+
- Derived work is credited in `NOTICE`, as required by Apache-2.0; derived code is never relicensed.
|
|
19
|
+
- Third-party review favours pinned, auditable versions (e.g. `dsh-agy@0.1.2`) so that what we link against is known and reproducible.
|
|
20
|
+
|
|
21
|
+
### 0.3 The hard boundary: no development-privacy leak
|
|
22
|
+
|
|
23
|
+
Open source does **not** mean publishing everything. The following must never reach git, the npm artifact, or any public channel:
|
|
24
|
+
|
|
25
|
+
- real credentials, tokens, passwords, API keys, private keys, `authorized_keys`;
|
|
26
|
+
- personal accounts / account-pool details, host aliases, exact machine paths, internal IPs;
|
|
27
|
+
- fault-investigation notes that describe a private machine or a specific personal incident (keep these in `docs/local/`).
|
|
28
|
+
|
|
29
|
+
When in doubt, **do not publish** — put the note in the local-only layer instead.
|
|
30
|
+
|
|
31
|
+
### 0.4 "Publishable documentation will be published"
|
|
32
|
+
|
|
33
|
+
Adopting the community norm, any document judged to be genuinely useful to contributors and free of development-privacy content **is expected to be published** (tracked in git, shipped via `files`, reachable from `README`), not merely written and left local. This includes: architecture, install/usage, contributor/release rules, changelog, and the compliance note. Documents that fail the §0.3 boundary check stay local-only. The publish/local split in §1 exists to make that call explicit and auditable.
|
|
34
|
+
|
|
35
|
+
### 0.5 Community commitments
|
|
36
|
+
|
|
37
|
+
- Welcome and respond to issues and PRs (see `CONTRIBUTING.md`).
|
|
38
|
+
- Keep a real changelog and a predictable release cadence (§5).
|
|
39
|
+
- Publish release notes and version tags so history is traceable.
|
|
40
|
+
- Keep git history atomic and conventional (§7); never commit secrets or mix unrelated concerns.
|
|
41
|
+
- Do not invent capabilities, pad releases, or impersonate vendors/clients (§5, `README` compliance note).
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 1. Document Layers: Publish vs Local-only
|
|
46
|
+
|
|
47
|
+
Every document in the repo belongs to one of two layers, and the two never mix:
|
|
48
|
+
|
|
49
|
+
| Layer | Location | In git / npm? | Examples | Requirements |
|
|
50
|
+
|---|---|---|---|---|
|
|
51
|
+
| **Publishable (public)** | Repo root: `README.md` + `README.zh-CN.md` + other community-language READMEs, `CONTRIBUTING.md`, `INSTALL.md`, `CHANGELOG.md`, `LICENSE`, `NOTICE`, and explicitly promoted generic `docs/` files (this rules doc, `docs/02-architecture.md` + `docs/02-architecture.zh-CN.md`) | ✅ git, shipped via `files` | architecture, install/usage, route table, compliance notes, contribution & release rules | privacy-free: no host aliases, accounts, credentials, absolute paths; external-facing tone |
|
|
52
|
+
| **Local-only (personal)** | `docs/local/` — investigation, risk and fault-analysis notes (e.g. `docs/local/01-research.md`, `docs/local/05-INVALID_REPLAY_STATE-调查.md`); `reference/` (vendored third-party source) | ❌ in `.gitignore`, never in `files` | concrete fault debugging, internal details, account-risk analysis | reference only; ignored by git by default |
|
|
53
|
+
|
|
54
|
+
**Hard constraints**
|
|
55
|
+
|
|
56
|
+
- `package.json` `files` whitelist contains **only** publishable docs; `docs/` must **not** be added wholesale — any doc shipped with the package is listed explicitly.
|
|
57
|
+
- `.gitignore` keeps `docs/local/`, `docs/` and `reference/` ignored. To promote a doc into version control, explicitly `git add -f` after moving it to the root or adopting the naming convention in §2.
|
|
58
|
+
- Before adding any doc, ask: *does an unrelated contributor need to see this?* Anything involving personal accounts, hosts, tokens, paths, regional-risk details or internal debugging goes to the local-only layer.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 2. Document Naming & "Document Version"
|
|
63
|
+
|
|
64
|
+
- Docs use `NN-<topic>.md`, numbered from `00` (`00-project-rules` is the fixed rule file — it is not re-versioned on every release).
|
|
65
|
+
- **A "new document version" exists when any of the following happens**:
|
|
66
|
+
- substantive content added/removed/changed (not just wording);
|
|
67
|
+
- a doc is split, merged, or added;
|
|
68
|
+
- `README.md` / `INSTALL.md` must be updated to stay consistent.
|
|
69
|
+
- A document's version **is the npm package version** (see §3); there is no separate doc versioning scheme.
|
|
70
|
+
|
|
71
|
+
### Language policy
|
|
72
|
+
|
|
73
|
+
- **`README.md` is English-first.** It also ships community translations selected for the widest open-source reach: `README.zh-CN.md` (简体中文), `README.ja.md` (日本語), `README.ko.md` (한국어), `README.pt-BR.md` (Português do Brasil), `README.es.md` (Español), `README.fr.md` (Français), `README.de.md` (Deutsch) and `README.ru.md` (Русский). All 9 files carry an identical language-switch line at the top so readers can jump between them, and every translation must be kept in sync with `README.md` (same sections, same version references).
|
|
74
|
+
- Any user-facing change to `README.md` implies updating **all** translations. If that is not feasible for a very-large change, translators can open follow-up PRs, but the language switch line must never be broken.
|
|
75
|
+
- Publishable docs under `docs/` are written English-first as well, to match the general-OSS publishing style. `docs/local/` may stay in whatever language the author prefers, since it is never published.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 3. Versioning & The Release Loop
|
|
80
|
+
|
|
81
|
+
[Semantic Versioning (SemVer)](https://semver.org/): `MAJOR.MINOR.PATCH`.
|
|
82
|
+
|
|
83
|
+
| Change | Version action |
|
|
84
|
+
|---|---|
|
|
85
|
+
| New public capability / route / provider | minor (in the `0.x` phase this bumps the second digit) |
|
|
86
|
+
| Bug fix, docs wording, process patch | patch |
|
|
87
|
+
| Breaking change to imports/config in an existing capability | major (pre-1.0, handled on a case-by-case basis) |
|
|
88
|
+
|
|
89
|
+
**The release loop (every document version → README → release) is a mandatory pipeline:**
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
new document version formed
|
|
93
|
+
│
|
|
94
|
+
▼
|
|
95
|
+
CHANGELOG.md updated (entry added under the matching release)
|
|
96
|
+
│
|
|
97
|
+
▼
|
|
98
|
+
README.md synced (new capability / new doc entry / new command / new notes)
|
|
99
|
+
│
|
|
100
|
+
▼
|
|
101
|
+
pnpm run check passes in the Docker sandbox
|
|
102
|
+
│
|
|
103
|
+
▼
|
|
104
|
+
version bumped (package.json + built artifact metadata, see §4)
|
|
105
|
+
│
|
|
106
|
+
▼
|
|
107
|
+
git commit + annotated tag v<version> (clean tree only)
|
|
108
|
+
│
|
|
109
|
+
▼
|
|
110
|
+
publish only after the verified local pack and explicit maintainer approval
|
|
111
|
+
│
|
|
112
|
+
▼
|
|
113
|
+
confirm GitHub release / milestone stays active
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Every time a document version is formed, the full loop above must run.** Never change docs without syncing README, and never update README without releasing.
|
|
117
|
+
|
|
118
|
+
**Commit, tag and tree hygiene** (detail in §7): each commit is conventional and atomic; generated `lib/` is committed with the source/build change that produced it; the release commit is made only on a clean tree; the annotated tag is `v<version>` and must match `package.json` and the top `CHANGELOG.md` heading.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 4. Automated Release Script
|
|
123
|
+
|
|
124
|
+
The repo provides `scripts/release.mjs` (see its header comment):
|
|
125
|
+
|
|
126
|
+
- `--dry-run` validates the current `CHANGELOG.md`/`package.json` version, verifies the already-built release artifacts, previews the real packed file list with lifecycle scripts disabled, and rejects local-only files.
|
|
127
|
+
- `--pack` rebuilds and verifies the release, then writes a local tarball under `output/`.
|
|
128
|
+
- The helper never bumps versions, commits, tags, pushes, or publishes. Those remain explicit maintainer operations after human approval.
|
|
129
|
+
|
|
130
|
+
Example:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# validate + preview only; no tarball, Git, or registry changes
|
|
134
|
+
node scripts/release.mjs --dry-run
|
|
135
|
+
|
|
136
|
+
# rebuild + verify + create a local candidate tarball
|
|
137
|
+
node scripts/release.mjs --pack
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
> Publishing and remote Git writes are intentionally outside the script.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## 5. Keeping the Project Active
|
|
145
|
+
|
|
146
|
+
"Active" is not about publishing many versions — it is a stable, predictable, handover-friendly rhythm:
|
|
147
|
+
|
|
148
|
+
- **Predictable release cadence**: run the release loop after every substantive feature PR; aim for at least one meaningful minor release per quarter to keep discoverability up.
|
|
149
|
+
- **Honest changelog**: accumulate pending entries under `Unreleased` and fold them into a version on release; never pad releases with empty entries.
|
|
150
|
+
- **Responsive PRs/issues**: keep the templates and conventions in `CONTRIBUTING.md` so any contributor knows how to open a PR.
|
|
151
|
+
- **CI & gates**: `pnpm run check` (lint + typecheck + test + build/verify) is a release precondition; CI also rebuilds committed `lib/` and rejects artifact drift.
|
|
152
|
+
- **Security stance**: the compliance note in `README` (own accounts only; no bulk accounts, resale, impersonation) is a hard line; any new provider or endpoint must respect it.
|
|
153
|
+
- **Docs/code in sync**: when adding or changing a capability, update `README.md` and `docs/02-architecture.md` (public layer) before releasing.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 6. Pre-Release Self-Check (Privacy Line)
|
|
158
|
+
|
|
159
|
+
Before every real release, verify:
|
|
160
|
+
|
|
161
|
+
- [ ] `npm pack --dry-run --json --ignore-scripts` output contains **nothing** matching `*调查*`, `docs/local/`, `reference/`, account/host aliases, tokens, or absolute paths.
|
|
162
|
+
- [ ] `README.md` / `INSTALL.md` reference only public, generic commands, domains and accounts.
|
|
163
|
+
- [ ] The `files` whitelist does **not** include the whole `docs/` directory.
|
|
164
|
+
- [ ] `CHANGELOG.md` has an entry matching the about-to-be-released version; pending notes have been folded from `Unreleased` into `## v<version>`.
|
|
165
|
+
- [ ] `pnpm run check` passes.
|
|
166
|
+
- [ ] `git status` is clean: no leftover source, docs, lockfile or `lib/` drift.
|
|
167
|
+
- [ ] The annotated tag will be `v<version>` and matches `package.json` plus the top `CHANGELOG.md` heading. Never move or reuse a published tag.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 7. Commits, Pushes & Tags
|
|
172
|
+
|
|
173
|
+
Contributor-facing wording lives in `CONTRIBUTING.md`. This section is the source of truth for maintainers.
|
|
174
|
+
|
|
175
|
+
### 7.1 Atomic conventional commits
|
|
176
|
+
|
|
177
|
+
- Messages follow [Conventional Commits](https://www.conventionalcommits.org/): `type(optional-scope): summary` in the imperative (`feat:`, `fix:`, `docs:`, `test:`, `refactor:`, `build:`, `ci:`, `chore:`). Optional scopes such as `M1` / `M3` or a module name are fine.
|
|
178
|
+
- **One coherent concern per commit.** Never mix documentation, build/toolchain and feature/fix changes unless they cannot be reviewed or built separately (a capability that is meaningless without its README/changelog note, or a source change that must ship with the `lib/` it generated).
|
|
179
|
+
- Build the tracked Dockerfile's `check` and `verify` targets before the commit. Do not install dependencies, typecheck, lint, test, build, or pack this plugin directly on a shared developer host. The build context is filtered by `.dockerignore`; dependencies download in their own stage, while all project-code `RUN` steps use `--network=none`. Never use privileged mode, credential mounts, the Docker socket, or host-directory bind mounts. Host networking is prohibited except for the narrow, explicitly authorized preview fallback below. Commit that passing slice promptly — do not leave a finished, verified change sitting uncommitted next to later work, and do not commit a red tree.
|
|
180
|
+
- **Host DSH boundary:** unless the maintainer explicitly requests it for the current operation, never install into, modify, stop, restart, or run validation against a DSH instance already installed on the shared host. Development checks and interactive Web previews use a dedicated Docker DSH instance with an isolated home/profile. A preview may publish an explicitly selected high host port on `0.0.0.0` for remote review, must not reuse the host DSH port or state directories, and must remain resource-limited and individually removable. Host networking is prohibited by default; it is allowed only after ordinary Docker port publishing has been proven unavailable and the maintainer explicitly authorizes that specific run. An authorized host-network preview must bind only pre-checked high ports, keep its DSH backend on a separate loopback high port, and never bind or probe the host DSH port.
|
|
181
|
+
- Generated `lib/` is a committed release artifact (git installs and the CI `git diff --exit-code -- lib` drift gate). Rebuild it and include it in the **same** commit as the `src/` or build-script change that produced it. Do not land stale `lib/` against newer source, and do not land a `lib/`-only commit unless the only change is a verified rebuild with no source delta.
|
|
182
|
+
- Secrets, credentials, tokens, private keys, `.env` files, host aliases, absolute machine paths, and local-only notes (`docs/local/`, `reference/`) never enter git (§0.3).
|
|
183
|
+
|
|
184
|
+
### 7.2 Pushes
|
|
185
|
+
|
|
186
|
+
- Feature branches are pushed as **checkpoints** at each version or milestone (branch names such as `work/<topic>-v0.3` are fine), not only when the PR is finished.
|
|
187
|
+
- Force-push is forbidden without **explicit approval**, including `--force-with-lease`, once a branch has been pushed. Default history is append-only. Never force-push `main` or a published release tag.
|
|
188
|
+
- Do not push a dirty or failing tree "to save it"; commit the passing slice first.
|
|
189
|
+
|
|
190
|
+
### 7.3 Changelog, versions and tags
|
|
191
|
+
|
|
192
|
+
- Day-to-day user-facing work accumulates under `CHANGELOG.md` → `## Unreleased`.
|
|
193
|
+
- A release folds `Unreleased` into `## v<version>`, bumps `package.json` (and any built artifact metadata) to that same version, and creates an **annotated** tag `v<version>` on a **clean** working tree. The top changelog heading, `package.json` version and tag name must be identical (the `v` prefix is tag/heading only).
|
|
194
|
+
- `scripts/release.mjs` does **not** bump, commit, tag, push or publish; those stay explicit maintainer steps after `pnpm run check`, `--dry-run` and `--pack` succeed.
|
|
195
|
+
- Never tag or publish from a dirty tree, and never move or reuse a published tag.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
> [**中文版**](02-architecture.zh-CN.md) · English
|
|
4
|
+
|
|
5
|
+
This document describes the internal architecture of `dsh-coding-subscription-oauth`. It is the source for the technical notes in `README.md` and is intended for contributors and maintainers.
|
|
6
|
+
|
|
7
|
+
## 1. Routes and native providers
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
Harness route pi-ai provider request authentication
|
|
11
|
+
────────────────────────────────────────────────────────────
|
|
12
|
+
grok-build grok-build xAI access token + Grok CLI headers
|
|
13
|
+
codex-oauth openai-codex OAuth token → apiKey override
|
|
14
|
+
kimi-code-oauth kimi-coding OAuth token → Authorization: Bearer
|
|
15
|
+
claude-code-oauth anthropic sk-ant-oat token → Claude Code headers
|
|
16
|
+
agy dsh-agy external dsh-agy own account pool
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
External routes and the pi-ai native ids are separated by `AliasLlmAdapter`. `PiAiAdapter` always sees the native provider id, so Codex tool-calls, Claude compatibility checks and the Kimi Anthropic transport do not break when a route is renamed.
|
|
20
|
+
|
|
21
|
+
"Authenticated" in model discovery is defined as an existing, structurally valid, refreshable OAuth credential; the selector does not probe upstream on every open. Credentials that upstream has revoked but are still locally valid are recognized during token refresh or inference, avoiding extra network requests on catalog load.
|
|
22
|
+
|
|
23
|
+
## 2. Host data flow
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
Settings / CLI
|
|
27
|
+
│
|
|
28
|
+
├─ GrokBuildWebAuth ── Grok custom PKCE/device
|
|
29
|
+
│ └─ .grok-build-auth.json
|
|
30
|
+
│
|
|
31
|
+
├─ SubscriptionWebAuth ── pi-ai OAuth login/refresh
|
|
32
|
+
│ ├─ Codex ── .codex-oauth-auth.json
|
|
33
|
+
│ ├─ Kimi ── .kimi-code-oauth-auth.json
|
|
34
|
+
│ └─ Claude ── .claude-code-oauth-auth.json
|
|
35
|
+
│
|
|
36
|
+
└─ OAuthImportSession ── read-only allowlisted CLI discovery
|
|
37
|
+
└─ explicit one-way Pull (preview ticket → dest store)
|
|
38
|
+
official CLI files are never written
|
|
39
|
+
|
|
40
|
+
OAuthProviderSession.resolveAccessToken()
|
|
41
|
+
└─ Models.getAuth(native id) # refresh-under-lock
|
|
42
|
+
└─ OAuthCredentialFileStore # 0600 + atomic write + cross-process lock
|
|
43
|
+
|
|
44
|
+
CapabilitySettingsController (default-off, applies: live)
|
|
45
|
+
└─ CapabilityRuntimeState
|
|
46
|
+
├─ Codex search / usage / gpt-image-2 images
|
|
47
|
+
├─ codex-oauth-fast (only after a fresh priority catalog)
|
|
48
|
+
└─ Grok Imagine (api.x.ai + XAI_API_KEY via DSH credentials)
|
|
49
|
+
|
|
50
|
+
ctx.llm route
|
|
51
|
+
└─ AliasLlmAdapter
|
|
52
|
+
└─ PiAiAdapter
|
|
53
|
+
└─ native pi-ai Provider.streamSimple()
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 3. Module responsibilities
|
|
57
|
+
|
|
58
|
+
- `store.ts`: one file owns one provider credential; keeps the legacy Grok store API; `invalidate()` backdates `expires` after an upstream AUTH rejection.
|
|
59
|
+
- `oauth-providers.ts`: Codex/Kimi/Claude definitions, route metadata, request token bridge.
|
|
60
|
+
- `oauth-session.ts`: login, refresh, static model catalog and model-selection cache.
|
|
61
|
+
- `oauth-sources.ts`: allowlisted official Grok/Codex/Kimi/Claude CLI discovery; hardened lstat/`O_NOFOLLOW`/owner/mode/regular-file/size reads; one-use preview tickets (five minutes, max 32); never writes official CLI files.
|
|
62
|
+
- `oauth-import-routes.ts`: same-origin Pull HTTP API (discover → preview → commit/cancel) into the destination store lock.
|
|
63
|
+
- `alias-adapter.ts`: translates Harness routes, does not modify pi-ai `model.provider`, and runs a credential gate before `listModels()`; unauthenticated or unreadable credentials return an empty catalog, and the provider group name is `(OAuth)`. On an AUTH finish it invalidates the stored token so the harness retry can refresh first.
|
|
64
|
+
- `adapter.ts`: composes Grok with the three subscription profiles; asks pi-ai for a 60 s remaining-validity floor and registers a retry policy that includes AUTH plus transient codes. Optionally wraps `codex-oauth-fast` as **Fast requested**.
|
|
65
|
+
- `auth-routes.ts`: legacy Grok API + the unified `/plugins/dsh-grok-build/oauth/*`; JSON writes use a 64 KiB bounded reader and return 400/413 for malformed/oversized bodies.
|
|
66
|
+
- `capability-settings.ts`: default-off live flags and limits (search 1–20, image count 1–4, artifact TTL 1 h–7 d).
|
|
67
|
+
- `capability-routes.ts`: secret-free capability snapshot plus optional Codex usage and Imagine credential-status routes.
|
|
68
|
+
- `capability-runtime.ts`: live bind/unbind of search, tools, and the Fast route after a fresh priority catalog.
|
|
69
|
+
- `capability-tools.ts`: optional Codex / Grok Imagine tool definitions; flags re-read at execute time.
|
|
70
|
+
- `codex-http.ts`: opt-in private `chatgpt.com/backend-api` client (HTTPS-only, first-party host).
|
|
71
|
+
- `codex-search.ts` / `codex-usage.ts` / `codex-images.ts`: opt-in search, quota, and fixed `gpt-image-2` generate/edit (edits require current-session top-level attachment ownership).
|
|
72
|
+
- `codex-model-capabilities.ts`: live Codex service-tier cache; fail-closed Fast eligibility; injects `service_tier: priority` and the routing hint.
|
|
73
|
+
- `grok-imagine.ts`: official `api.x.ai` Imagine client (`grok-imagine-image-2.0` / `grok-imagine-video-1.5`); `XAI_API_KEY` via DSH credentials only; MIME/size/time/redirect/DNS download controls; frozen hosts `imgen.x.ai`, `videogen.x.ai`, `vidgen.x.ai`.
|
|
74
|
+
- `imagine-routes.ts`: same-origin loopback GET routes for generated images and video artifacts.
|
|
75
|
+
- `media-store.ts`: owner-private artifact store (256 MiB per-object and aggregate unique-byte hard caps, seven days).
|
|
76
|
+
- `client/`: four native account cards, CLI Pull, capability switches, gateway controls, and the external Antigravity status card.
|
|
77
|
+
- `proxy.ts`: process-wide undici dispatcher, but proxies only a reviewed domain whitelist.
|
|
78
|
+
- `gateway*.ts`: opt-in isolated loopback OpenAI/Anthropic-compatible HTTP server (default off; independent of the DSH web port).
|
|
79
|
+
|
|
80
|
+
## 4. Web API
|
|
81
|
+
|
|
82
|
+
Unified interface:
|
|
83
|
+
|
|
84
|
+
```text
|
|
85
|
+
GET /plugins/dsh-grok-build/oauth/status
|
|
86
|
+
POST /plugins/dsh-grok-build/oauth/login
|
|
87
|
+
POST /plugins/dsh-grok-build/oauth/code
|
|
88
|
+
POST /plugins/dsh-grok-build/oauth/cancel
|
|
89
|
+
POST /plugins/dsh-grok-build/oauth/logout
|
|
90
|
+
POST /plugins/dsh-grok-build/oauth/models
|
|
91
|
+
|
|
92
|
+
GET /plugins/dsh-grok-build/oauth/sources
|
|
93
|
+
POST /plugins/dsh-grok-build/oauth/sources/preview
|
|
94
|
+
POST /plugins/dsh-grok-build/oauth/sources/commit
|
|
95
|
+
POST /plugins/dsh-grok-build/oauth/sources/cancel
|
|
96
|
+
|
|
97
|
+
GET /plugins/dsh-grok-build/capabilities
|
|
98
|
+
PATCH /plugins/dsh-grok-build/capabilities
|
|
99
|
+
PUT /plugins/dsh-grok-build/capabilities
|
|
100
|
+
GET /plugins/dsh-grok-build/codex/usage
|
|
101
|
+
GET /plugins/dsh-grok-build/imagine/credential-status
|
|
102
|
+
GET /plugins/dsh-grok-build/imagine/images/<id>
|
|
103
|
+
GET /plugins/dsh-grok-build/imagine/media/<id>
|
|
104
|
+
GET /plugins/dsh-grok-build/gateway
|
|
105
|
+
PATCH /plugins/dsh-grok-build/gateway
|
|
106
|
+
POST /plugins/dsh-grok-build/gateway/rotate
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Write endpoints take `provider: grok|codex|kimi|claude` in the body. Responses contain only status, authorization URL, device user code, model ids and a non-sensitive expiry; they never contain access/refresh tokens. JSON request bodies are capped at 64 KiB before parsing.
|
|
110
|
+
|
|
111
|
+
`/oauth/sources` is read-only discovery. Preview/commit is the explicit one-way Pull (tickets one-use, five minutes, max 32). Capability writes are secret-free compare-and-swap snapshots in the `coding-subscription-oauth` settings section and apply live. Seven flags default off; `searchResults` is 1–20 (default 5), `imageCount` is 1–4 (default 1), and `videoArtifactTtlMs` is 1 hour–7 days (default 7 days; UI 1–168 hours); decreases rewrite/clean existing expiries immediately, while increases affect only new artifacts. Imagine download routes are same-origin loopback GETs; they never return a signed upstream URL.
|
|
112
|
+
|
|
113
|
+
The legacy `/plugins/dsh-grok-build/auth/*` endpoints remain registered and reuse the same Grok controller.
|
|
114
|
+
|
|
115
|
+
## 5. Antigravity
|
|
116
|
+
|
|
117
|
+
This project does not replicate the private Google Antigravity protocol. The profile separately installs `dsh-agy@0.1.2`, which provides the `agy` route. Because the `/agy` dashboard in that version includes an export API with no authentication of its own, trusted-host deployments should disable `dsh-agy-web` in the profile's final `cordis.patch.yml` (see `INSTALL.md`) and keep only the host adapter and CLI. The profile uses a pnpm patch with a lockfile hash: with no Google session, `listModels()` returns empty; after authentication the provider group name is `Google Antigravity (OAuth)`.
|
|
118
|
+
|
|
119
|
+
## 6. Compatibility
|
|
120
|
+
|
|
121
|
+
The canonical package and repository name is **`dsh-coding-subscription-oauth`**. The previous GitHub URL still resolves to the same `main`, so old `dsh plugin add github:lninghaha/dsh-grok-build` commands continue to install the renamed package. The first public npm/GitHub Release was **`0.4.1`**. The current release is **`0.5.0`** (`dsh plugin --profile web add dsh-coding-subscription-oauth@0.5.0`). GitHub and local tarball installs remain valid.
|
|
122
|
+
|
|
123
|
+
Stable on-disk / in-process identifiers (do not rename without a migration):
|
|
124
|
+
|
|
125
|
+
- Cordis id: `llm-grok-build-oauth`
|
|
126
|
+
- Settings HTTP API: `/plugins/dsh-grok-build/oauth/*`, `/plugins/dsh-grok-build/capabilities`, `/plugins/dsh-grok-build/codex/usage`, `/plugins/dsh-grok-build/imagine/*`, and legacy `/plugins/dsh-grok-build/auth/*`
|
|
127
|
+
- Credential files: `$DSH_HOME/.grok-build-auth.json` and the other `*-oauth-auth.json` files
|
|
128
|
+
- Imagine credential: DSH credentials reference `XAI_API_KEY` (never Grok OAuth, never process-env fallback)
|
|
129
|
+
- CLI: `dsh-coding-oauth` (primary) and `dsh-grok-build` (alias)
|
|
130
|
+
- LLM routes: `grok-build`, `codex-oauth`, `kimi-code-oauth`, `claude-code-oauth`; optional `codex-oauth-fast` (v0.4.0, advertised only when a fresh live catalog lists `priority`)
|
|
131
|
+
|
|
132
|
+
New routes use the `*-oauth` alias and do not occupy `openai`, `xai` or `kimi-coding`. In v0.3.0 the `grok-build` fallback/default advances to `grok-4.6`; saved user defaults still win.
|