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.
Files changed (178) hide show
  1. package/CHANGELOG.md +136 -0
  2. package/CONTRIBUTING.md +109 -0
  3. package/INSTALL.md +220 -0
  4. package/LICENSE +19 -0
  5. package/NOTICE +11 -0
  6. package/README.de.md +254 -0
  7. package/README.es.md +254 -0
  8. package/README.fr.md +254 -0
  9. package/README.ja.md +254 -0
  10. package/README.ko.md +254 -0
  11. package/README.md +286 -0
  12. package/README.pt-BR.md +254 -0
  13. package/README.ru.md +254 -0
  14. package/README.zh-CN.md +271 -0
  15. package/cordis.patch.yml +13 -0
  16. package/docs/00-project-rules.md +195 -0
  17. package/docs/02-architecture.md +132 -0
  18. package/docs/02-architecture.zh-CN.md +128 -0
  19. package/lib/adapter.d.ts +24 -0
  20. package/lib/adapter.d.ts.map +1 -0
  21. package/lib/alias-adapter.d.ts +43 -0
  22. package/lib/alias-adapter.d.ts.map +1 -0
  23. package/lib/auth-routes.d.ts +155 -0
  24. package/lib/auth-routes.d.ts.map +1 -0
  25. package/lib/auth.d.ts +29 -0
  26. package/lib/auth.d.ts.map +1 -0
  27. package/lib/bin.d.ts +6 -0
  28. package/lib/bin.d.ts.map +1 -0
  29. package/lib/bin.js +27591 -0
  30. package/lib/bin.js.map +7 -0
  31. package/lib/capability-routes.d.ts +43 -0
  32. package/lib/capability-routes.d.ts.map +1 -0
  33. package/lib/capability-runtime.d.ts +56 -0
  34. package/lib/capability-runtime.d.ts.map +1 -0
  35. package/lib/capability-settings.d.ts +263 -0
  36. package/lib/capability-settings.d.ts.map +1 -0
  37. package/lib/capability-tools.d.ts +50 -0
  38. package/lib/capability-tools.d.ts.map +1 -0
  39. package/lib/catalog.d.ts +53 -0
  40. package/lib/catalog.d.ts.map +1 -0
  41. package/lib/client.js +3 -0
  42. package/lib/client.js.map +7 -0
  43. package/lib/codex-http.d.ts +77 -0
  44. package/lib/codex-http.d.ts.map +1 -0
  45. package/lib/codex-images.d.ts +109 -0
  46. package/lib/codex-images.d.ts.map +1 -0
  47. package/lib/codex-model-capabilities.d.ts +112 -0
  48. package/lib/codex-model-capabilities.d.ts.map +1 -0
  49. package/lib/codex-search.d.ts +96 -0
  50. package/lib/codex-search.d.ts.map +1 -0
  51. package/lib/codex-usage.d.ts +79 -0
  52. package/lib/codex-usage.d.ts.map +1 -0
  53. package/lib/gateway-anthropic-messages.d.ts +8 -0
  54. package/lib/gateway-anthropic-messages.d.ts.map +1 -0
  55. package/lib/gateway-auth.d.ts +22 -0
  56. package/lib/gateway-auth.d.ts.map +1 -0
  57. package/lib/gateway-backend.d.ts +62 -0
  58. package/lib/gateway-backend.d.ts.map +1 -0
  59. package/lib/gateway-body.d.ts +9 -0
  60. package/lib/gateway-body.d.ts.map +1 -0
  61. package/lib/gateway-config.d.ts +24 -0
  62. package/lib/gateway-config.d.ts.map +1 -0
  63. package/lib/gateway-http.d.ts +16 -0
  64. package/lib/gateway-http.d.ts.map +1 -0
  65. package/lib/gateway-openai-chat.d.ts +8 -0
  66. package/lib/gateway-openai-chat.d.ts.map +1 -0
  67. package/lib/gateway-openai-responses.d.ts +8 -0
  68. package/lib/gateway-openai-responses.d.ts.map +1 -0
  69. package/lib/gateway-parse.d.ts +10 -0
  70. package/lib/gateway-parse.d.ts.map +1 -0
  71. package/lib/gateway-protocol.d.ts +47 -0
  72. package/lib/gateway-protocol.d.ts.map +1 -0
  73. package/lib/gateway-routes.d.ts +21 -0
  74. package/lib/gateway-routes.d.ts.map +1 -0
  75. package/lib/gateway.d.ts +48 -0
  76. package/lib/gateway.d.ts.map +1 -0
  77. package/lib/grok-imagine.d.ts +271 -0
  78. package/lib/grok-imagine.d.ts.map +1 -0
  79. package/lib/grok-import.d.ts +21 -0
  80. package/lib/grok-import.d.ts.map +1 -0
  81. package/lib/http-json.d.ts +10 -0
  82. package/lib/http-json.d.ts.map +1 -0
  83. package/lib/ids.d.ts +33 -0
  84. package/lib/ids.d.ts.map +1 -0
  85. package/lib/imagine-routes.d.ts +59 -0
  86. package/lib/imagine-routes.d.ts.map +1 -0
  87. package/lib/index.d.ts +69 -0
  88. package/lib/index.d.ts.map +1 -0
  89. package/lib/index.js +35355 -0
  90. package/lib/index.js.map +7 -0
  91. package/lib/invariant.d.ts +9 -0
  92. package/lib/invariant.d.ts.map +1 -0
  93. package/lib/invariant.js +14 -0
  94. package/lib/invariant.js.map +7 -0
  95. package/lib/kimi-errors.d.ts +13 -0
  96. package/lib/kimi-errors.d.ts.map +1 -0
  97. package/lib/media-store.d.ts +130 -0
  98. package/lib/media-store.d.ts.map +1 -0
  99. package/lib/oauth-import-routes.d.ts +52 -0
  100. package/lib/oauth-import-routes.d.ts.map +1 -0
  101. package/lib/oauth-providers.d.ts +26 -0
  102. package/lib/oauth-providers.d.ts.map +1 -0
  103. package/lib/oauth-session.d.ts +40 -0
  104. package/lib/oauth-session.d.ts.map +1 -0
  105. package/lib/oauth-sources.d.ts +205 -0
  106. package/lib/oauth-sources.d.ts.map +1 -0
  107. package/lib/oauth.d.ts +79 -0
  108. package/lib/oauth.d.ts.map +1 -0
  109. package/lib/provider.d.ts +38 -0
  110. package/lib/provider.d.ts.map +1 -0
  111. package/lib/proxy.d.ts +17 -0
  112. package/lib/proxy.d.ts.map +1 -0
  113. package/lib/redact.d.ts +5 -0
  114. package/lib/redact.d.ts.map +1 -0
  115. package/lib/session.d.ts +40 -0
  116. package/lib/session.d.ts.map +1 -0
  117. package/lib/store.d.ts +46 -0
  118. package/lib/store.d.ts.map +1 -0
  119. package/lib/web-origin.d.ts +10 -0
  120. package/lib/web-origin.d.ts.map +1 -0
  121. package/lib/web-routes.d.ts +20 -0
  122. package/lib/web-routes.d.ts.map +1 -0
  123. package/package.json +185 -0
  124. package/patches/dsh-agy@0.1.2.patch +25 -0
  125. package/scripts/release.mjs +166 -0
  126. package/scripts/smoke-deployed-routes.mjs +146 -0
  127. package/scripts/verify-deployed-catalog.mjs +87 -0
  128. package/src/adapter.ts +282 -0
  129. package/src/alias-adapter.ts +152 -0
  130. package/src/auth-routes.ts +871 -0
  131. package/src/auth.ts +67 -0
  132. package/src/bin.ts +350 -0
  133. package/src/capability-routes.ts +275 -0
  134. package/src/capability-runtime.ts +313 -0
  135. package/src/capability-settings.ts +657 -0
  136. package/src/capability-tools.ts +666 -0
  137. package/src/catalog.ts +271 -0
  138. package/src/client/GrokBuildSettings.tsx +2221 -0
  139. package/src/client/index.tsx +37 -0
  140. package/src/client/locales.ts +421 -0
  141. package/src/codex-http.ts +447 -0
  142. package/src/codex-images.ts +485 -0
  143. package/src/codex-model-capabilities.ts +320 -0
  144. package/src/codex-search.ts +245 -0
  145. package/src/codex-usage.ts +263 -0
  146. package/src/gateway-anthropic-messages.ts +84 -0
  147. package/src/gateway-auth.ts +100 -0
  148. package/src/gateway-backend.ts +274 -0
  149. package/src/gateway-body.ts +49 -0
  150. package/src/gateway-config.ts +76 -0
  151. package/src/gateway-http.ts +104 -0
  152. package/src/gateway-openai-chat.ts +124 -0
  153. package/src/gateway-openai-responses.ts +53 -0
  154. package/src/gateway-parse.ts +224 -0
  155. package/src/gateway-protocol.ts +52 -0
  156. package/src/gateway-routes.ts +152 -0
  157. package/src/gateway.ts +242 -0
  158. package/src/grok-imagine.ts +1627 -0
  159. package/src/grok-import.ts +151 -0
  160. package/src/http-json.ts +82 -0
  161. package/src/ids.ts +45 -0
  162. package/src/imagine-routes.ts +461 -0
  163. package/src/index.ts +598 -0
  164. package/src/invariant.ts +17 -0
  165. package/src/kimi-errors.ts +26 -0
  166. package/src/media-store.ts +927 -0
  167. package/src/oauth-import-routes.ts +314 -0
  168. package/src/oauth-providers.ts +152 -0
  169. package/src/oauth-session.ts +183 -0
  170. package/src/oauth-sources.ts +1104 -0
  171. package/src/oauth.ts +620 -0
  172. package/src/provider.ts +128 -0
  173. package/src/proxy.ts +99 -0
  174. package/src/redact.ts +72 -0
  175. package/src/session.ts +218 -0
  176. package/src/store.ts +217 -0
  177. package/src/web-origin.ts +60 -0
  178. package/src/web-routes.ts +75 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,136 @@
1
+ # Changelog
2
+
3
+ All notable changes to `dsh-coding-subscription-oauth` are documented here, following the release loop in `docs/00-project-rules.md`. Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). Versioning follows [SemVer](https://semver.org/).
4
+
5
+ ## Unreleased
6
+
7
+ ## v0.5.0 - 2026-08-17
8
+
9
+ ### Added
10
+
11
+ - Add an opt-in local API gateway (`gateway.enabled`, default off) that binds loopback-only and serves `/healthz`, `/v1/models`, streaming `POST /v1/chat/completions`, `POST /v1/responses`, and `POST /v1/messages` from signed-in subscription sessions.
12
+ - Let Settings copy the OpenAI/Anthropic base URLs and the current Bearer key. Loopback `POST /gateway/reveal` returns the current key without rotating it; rotate stays a confirmed destructive action.
13
+ - Let Settings change the gateway listen port with Apply or Random (18100–18999). The chosen port is stored in the owner-only gateway document and the listener rebinds when it is already running.
14
+
15
+ ### Changed
16
+
17
+ - Rebuild Settings as four top tabs (Accounts, Gateway, Capabilities, About). Signed-in account cards stay collapsed until expanded, CLI pull preview is full-width, and Imagine status sits on Capabilities.
18
+
19
+ ## v0.4.1 - 2026-08-17
20
+
21
+ ### Added
22
+
23
+ - Add accessible live numeric controls for `searchResults`, `imageCount`, and video artifact retention (shown as 1–168 hours), using the same compare-and-swap conflict handling as capability switches. Lowering retention rewrites and cleans existing expiries; raising it affects only new artifacts.
24
+ - Add a fast `check:next` Docker development gate (`lint` + `typecheck` + tests) before the full release build gate.
25
+
26
+ ### Changed
27
+
28
+ - Resolve the Codex search model at call time so sign-in, sign-out, and live catalog changes do not leave a stale model captured by an existing provider.
29
+ - Clarify browser, device-code, and manual redirect/code sign-in guidance; use the profile-aware Antigravity command `dsh plugin --profile web exec dsh-agy login --headless`.
30
+ - Raise the `undici` floor to `^7.24.8` so scoped `socks5://` proxies are supported.
31
+ - Document the first public install path as `dsh plugin --profile web add dsh-coding-subscription-oauth@0.4.1`, matching other DSH plugins.
32
+
33
+ ### Fixed
34
+
35
+ - Declare image input on the Grok 4.5 and Grok 4.6 baseline descriptors so both fallback and live-derived catalog entries accept image attachments instead of failing locally as unsupported.
36
+ - Resolve subscription requests from the refreshed access token persisted by each OAuth session. This prevents Kimi's header-only `Authorization: Bearer` auth result from being misclassified as “not signed in” merely because it has no `auth.apiKey` field.
37
+ - Treat Kimi Code's HTTP 401 `authentication_error` that says a model `supports only 256K context` as `CONTEXT_WINDOW_EXCEEDED`. The previous AUTH classification invalidated a still-valid token and retried a request that cannot succeed.
38
+ - Strip `user:pass@` from the CLI proxy line, and when a scoped proxy is installed append a `CODING_OAUTH_PROXY` reachability hint to Grok discovery, token, and live-catalog transport errors.
39
+ - Preserve composition capability defaults before Settings is injected and after a Settings service is replaced or disposed; contain asynchronous settings-listener failures; keep empty PATCH writes revision-checked but side-effect free.
40
+ - Make generated media download filenames safe for `Content-Disposition` while preserving opaque DSH attachment ids.
41
+ - Dispose in-flight Grok Imagine API/download work before awaiting media cleanup, isolate caller-owned video-poll cancellation, and remove an artifact if cancellation wins during persistence.
42
+ - Finish Settings disposal even when an injected watch disposer throws, while reporting the contained failure.
43
+ - Reject owner-only or group/world-writable npm package entries and require the packed CLI to remain executable.
44
+ - Close preview-proxy WebSocket halves when either side ends so isolated proxy tests and shutdown cannot hang on leftover upgrade pipes.
45
+
46
+ ### Security
47
+
48
+ - Require Grok discovery to declare the exact configured issuer identity, pin authorization/token endpoints to its approved origin, refuse redirects, bound discovery/token responses and pasted authorization codes, and redact every repeated opaque credential-shaped diagnostic.
49
+ - Reject unknown, secret-shaped, mistyped, fractional, and out-of-range capability writes instead of silently coercing or clamping caller-authored values.
50
+ - Add a 60-second Codex request ceiling that covers response streaming, plus cancellation-aware stream cleanup; strengthen Imagine request-id, prompt, base64, redirect, MIME, size, and cancellation boundaries.
51
+
52
+ ## v0.4.0 - 2026-08-16
53
+
54
+ ### Added
55
+
56
+ - Add read-only Settings discovery of allowlisted official Grok / Codex / Kimi / Claude CLI OAuth files, plus an explicit one-way manual Pull: discover → preview → conflict/fingerprint check → overwrite confirmation. Official CLI files are never written.
57
+ - Add default-off live optional capabilities: Codex search, usage/quota, image generation/edit, Fast, and Grok Imagine image/video. Limits: search results 1–20, image count 1–4, artifact TTL 1 hour–7 days. A secret-free `capabilities` composition base is optional; user settings override it.
58
+ - Advertise `codex-oauth-fast` only after a fresh live catalog lists at least one `priority`-eligible model. Requests send `service_tier: priority` and a routing hint. The UI says **Fast requested** and does not guarantee latency or upstream honor.
59
+ - Add opt-in Codex private `chatgpt.com/backend-api` endpoints. Image generation uses the fixed model `gpt-image-2`. Image edit requires current-session top-level attachment ownership.
60
+ - Add Grok Imagine against official `https://api.x.ai` with `grok-imagine-image-2.0` and `grok-imagine-video-1.5`, using a separate DSH credential reference `XAI_API_KEY` (never Grok OAuth, never a process-env fallback).
61
+ - Serve generated outputs on same-origin loopback routes under `/plugins/dsh-grok-build/imagine/*`. Remote downloads apply MIME / size / time / redirect / DNS controls from frozen hosts `imgen.x.ai`, `videogen.x.ai`, and `vidgen.x.ai`. The private artifact store hard-caps both one object and aggregate unique object bytes at 256 MiB, with retention capped at seven days.
62
+
63
+ ### Changed
64
+
65
+ - Add a tracked multi-stage Docker sandbox for networkless check/verify, generated artifact export, local candidate packaging, and a script-disabled isolated consumer install.
66
+ - Settings CLI synchronization is a manual Pull, not auto-import. Discovery stays automatic and read-only; writing the dsh store still requires preview and an explicit confirm.
67
+ - Capability switches apply live; turning one off withdraws the matching search provider, tools, or Fast route without a restart.
68
+
69
+ ### Fixed
70
+
71
+ - Bound in-memory Pull preview tickets to one-use, a five-minute TTL, and a process maximum of 32 so credential-bearing preview material cannot accumulate.
72
+
73
+ ### Security
74
+
75
+ - Harden official CLI reads: reject symlinks, non-regular files, non-owner files, group/other access, and oversized documents; open with `O_NOFOLLOW`; never write the official CLI path.
76
+ - Keep Imagine media on frozen xAI output hosts with DNS pinning and blocked private/loopback addresses; never return a signed upstream URL to the client.
77
+
78
+ ## v0.3.0
79
+
80
+ ### Added
81
+
82
+ - Add a provider retry policy for the four OAuth routes: transient failures (`RATE_LIMIT`/`SERVER`/`TIMEOUT`/`TRANSPORT`/`EMPTY_RESPONSE`) **and `AUTH`** now retry with exponential backoff (default 2 retries, 500 ms → 10 s, 10% jitter) instead of killing the turn.
83
+ - Add AUTH-failure credential invalidation: when an upstream rejects a locally-valid token with 401/403, the stored credential's expiry is backdated so the retried step refreshes before reuse — recovering the stale-token 401 race without user-visible failure.
84
+ - Add an optional `retryPolicy` plugin config (harness `RetryPolicySchema`) to override the built-in policy per deployment.
85
+
86
+ ### Changed
87
+
88
+ - Migrate the package toolchain from npm/tsdown to pnpm 11, TypeScript 6, Biome, and an esbuild multi-entry server/client build with declaration emit, promote/verify, and CI. Published package identity, dual CLI, Cordis/HTTP/credential identifiers, and `pi-ai` 0.84.2 stay unchanged.
89
+ - Require Node.js 22.19+ (or 24+) for the TypeScript 6/esbuild release pipeline and runtime bundle.
90
+ - Upgrade `@earendil-works/pi-ai` to `^0.84.2`: OAuth access tokens now refresh proactively five minutes before the stored expiry (previously only at the exact expiry instant, which raced server-side revocation on the Kimi/Codex routes), with a 15 s refresh timeout.
91
+ - Request OAuth access tokens with an explicit minimum remaining validity (60 s); a refresh that returns an even-shorter-lived token hard-fails instead of being handed to a request.
92
+ - Translate a rejected token refresh (revoked refresh token / dead grant) into `MISSING_CREDENTIAL` with a sign-in prompt rather than surfacing a bare upstream 401, and never retry it.
93
+ - Quota exhaustion stays outside the retryable set so a billing-limit response fails fast with its real message instead of the generic "API key is invalid".
94
+ - Expand README (all languages) with a searchable “problems this plugin solves” table covering SuperGrok vs `api.x.ai`, AUTH/`API key is invalid`, `INVALID_REPLAY_STATE`, grok-4.6 `xhigh`, Kimi Bearer vs `x-api-key`, remote device login and China-direct Kimi.
95
+ - Rename the published project to **`dsh-coding-subscription-oauth`**. The old `dsh-grok-build` name only covered the first provider. Cordis id, HTTP `/plugins/dsh-grok-build/*` paths, credential files and the `dsh-grok-build` CLI alias stay compatible.
96
+
97
+ ### Fixed
98
+
99
+ - Fix the stale-token 401 turn failure (`API key is invalid` banner) observed on the Kimi Code OAuth route when an access token expired mid-session: the turn now refreshes and retries transparently.
100
+ - Expose Grok 4.6 `xhigh` reasoning effort. Live `/models-v2` already returns `reasoning_efforts` including xhigh, but the plugin previously kept only model ids and materialized grok-4.6 from the grok-4.5 template. pi-ai hides xhigh unless that key is an explicit non-null mapping. The catalog now applies live effort lists; the baseline ships grok-4.6 with xhigh while grok-4.5 stays low/medium/high.
101
+ - Invalidate credentials on an `AUTH` finish even when that same finish also carries replay state, then rewrite the replay provider without skipping the refresh path.
102
+ - Bound OAuth JSON request bodies to 64 KiB (400 for malformed JSON, 413 for oversized bodies) and stream the live model catalog through a real 4 MiB ceiling.
103
+ - Contain startup cache/catalog failures and redact token-like material from refresh diagnostics instead of retaining it in user-visible errors or error causes.
104
+
105
+ ## v0.2.0
106
+
107
+ ### Added
108
+
109
+ - Add unified `/plugins/dsh-grok-build/oauth/*` API across Grok, Codex, Kimi and Claude.
110
+ - Add `codex-oauth`, `kimi-code-oauth` and `claude-code-oauth` routes alongside the preserved Grok Build and native API-key routes.
111
+ - Add the Coding OAuth settings page with per-provider sign-in, model selection and status cards.
112
+ - Add pinned `dsh-agy@0.1.2` integration for Google Antigravity and a safe patch that hides unauthenticated models and labels the provider `(OAuth)`.
113
+ - Add authentication-gated model discovery: unauthenticated OAuth routes expose no models, while authenticated providers are explicitly labelled `(OAuth)`.
114
+ - Add `verify:deployed` and `smoke:deployed` scripts for live-deployment verification.
115
+ - Add plugin-level scoped proxy configuration (`config.proxy`) and Kimi direct-connect default.
116
+ - Add high-contrast settings actions and localized community README translations.
117
+
118
+ ### Fixed
119
+
120
+ - Fix Kimi OAuth wire authentication so the final request uses `Authorization: Bearer` without an extra Anthropic `x-api-key`.
121
+ - Fix OAuth catalog refresh so listeners cannot make a successful login/logout appear failed, and cleanup failures cannot leave stale models visible.
122
+ - Fix OAuth route replay state so Codex/Kimi assistant messages keep the Harness route provider id and remain replayable across multi-turn conversations.
123
+ - Heal older poisoned OAuth replay metadata at request time and strip replay state when switching between sibling OAuth routes.
124
+ - Make deployment smoke require explicit `DSH_RESTORE_PROVIDER`/`DSH_RESTORE_MODEL`, then restore that default after testing.
125
+
126
+ ### Security
127
+
128
+ - Store all OAuth credential files as owner-only `0600` with atomic writes and cross-process locks.
129
+ - Keep OAuth tokens out of HTTP status responses, logs and the settings UI.
130
+ - Document disabling the unauthenticated `dsh-agy-web` dashboard on trusted-host deployments.
131
+
132
+ ## v0.1.0
133
+
134
+ - Initial release: Grok Build device OAuth, `import`, dynamic `/v1/models-v2` catalog and Responses streaming inference.
135
+ - `dsh-grok-build` CLI with login/import/status/logout.
136
+ - Web settings section for Grok Build account.
@@ -0,0 +1,109 @@
1
+ # Contributing
2
+
3
+ Welcome! `dsh-coding-subscription-oauth` is an open-source coding-subscription OAuth plugin for DeepSeek Harness. We appreciate issue reports, questions and pull requests. Read `docs/00-project-rules.md` first — it defines the release loop, versioning, commit/push hygiene and the publish vs local-only document split that every contribution must respect.
4
+
5
+ ## Code of Conduct
6
+
7
+ - Be respectful and constructive in issues, PRs and reviews.
8
+ - Only ever use coding subscriptions you own. The project does not support bulk accounts, quota resale, remote relay, paywall bypass or client impersonation — see the compliance note in `README.md`.
9
+
10
+ ## Getting started
11
+
12
+ Development verification for this plugin runs only in an isolated Docker build sandbox; do not run installs, builds, tests, typechecks, linters or package checks directly on a shared developer host. The tracked `Dockerfile` copies the filtered source into the image (never credentials), downloads dependencies in a dedicated stage, then runs project code with `--network=none`. Do not use privileged mode, credential or host-directory bind mounts, or the Docker socket. Tests use no published ports. The narrowly controlled interactive Web preview below is the only port-publishing exception; host networking remains prohibited unless its documented fallback conditions are all met.
13
+
14
+ ```bash
15
+ docker build --target check --build-arg NODE_VERSION=22.19.0 \
16
+ --resource memory=3g --resource cpu-quota=200000 \
17
+ --tag test-dsh-coding-oauth:check .
18
+
19
+ docker build --target verify --build-arg NODE_VERSION=22.19.0 \
20
+ --resource memory=3g --resource cpu-quota=200000 \
21
+ --tag test-dsh-coding-oauth:verify .
22
+ ```
23
+
24
+ The `artifacts`, `package`, `inspect`, and `isolated-install` targets cover generated `lib/`, the candidate tarball, release inspection, and a script-disabled consumer install.
25
+
26
+ ### Isolated Web preview
27
+
28
+ `docker/run-preview.sh` is the only supported interactive preview launcher. It builds `web-preview` offline from two auditable inputs: this checkout's committed `lib/` and a BuildKit named context containing an installed `@deepseek-ai/dsh@0.1.0-rc.6` **program package**. Point `DSH_INSTALL_DIR` at that package directory, never at a DSH home/profile or any credential directory:
29
+
30
+ ```bash
31
+ export DSH_INSTALL_DIR=/path/to/node_modules/@deepseek-ai/dsh
32
+ export DSH_PREVIEW_AUTHORITIES=review-host.example:17800
33
+ ./docker/run-preview.sh
34
+ ```
35
+
36
+ The launcher defaults to Docker bridge networking and `0.0.0.0:17800`, checks the allowed high-port ranges, and enforces a non-root user, read-only root filesystem, dropped capabilities, no-new-privileges, CPU/memory/PID limits, isolated named volumes, and tmpfs runtime state. The DSH backend remains on a separate loopback-only high port. It does not mount, modify, restart, or validate against an existing host DSH. If provider endpoints require an outbound proxy, set `DSH_PREVIEW_PROXY` explicitly.
37
+
38
+ The launcher prints a command for reading the runtime-generated bootstrap token from the container. Append it to the printed local or allowlisted remote URL as `?preview_token=<token>` using a private channel. The proxy exchanges it once for an HttpOnly, SameSite=Strict cookie and redirects to a token-free URL. Treat both the bootstrap URL and the isolated preview volumes as credentials; never paste either into logs, issues, commits, or chat.
39
+
40
+ Host networking is **not** a normal preview mode. It may be selected only after a minimal container proves ordinary Docker port publishing unavailable and the maintainer explicitly approves that one run. The explicit guard is:
41
+
42
+ ```bash
43
+ DSH_PREVIEW_NETWORK=host \
44
+ DSH_PREVIEW_HOST_NETWORK_CONFIRMED=yes \
45
+ ./docker/run-preview.sh
46
+ ```
47
+
48
+ Even then, the launcher permits only the isolated high-port ranges and refuses occupied preview/backend ports. Stop the preview with the exact `docker rm -f <container>` command printed by the launcher. Remove its named volumes only after confirming they contain no OAuth credentials that need to be retained.
49
+
50
+ This repo also ships a Grok Build CLI (`dsh-coding-oauth`, legacy `dsh-grok-build`), an OAuth settings page, and verification scripts for a live deployment (`verify:deployed` / `smoke:deployed`). Those exercise real providers, so they are meant for maintainer/dev workflows, not for CI.
51
+
52
+ ## Development flow
53
+
54
+ 1. Open an issue describing the change (or link an existing one) so scope is agreed first.
55
+ 2. Branch from the default branch. Keep commits atomic and conventional — see **Commits & pushes** below.
56
+ 3. When you change a capability or add a doc, update `README.md` (and the community translations added in `docs/00-project-rules.md` §2 if user-facing) and the relevant entries in `docs/` (public layer), **and** add a changelog entry under `Unreleased` in `CHANGELOG.md`.
57
+ 4. Build the Docker `check` and `verify` targets until green, then commit that passing slice promptly (do not stack later work on an uncommitted green tree).
58
+ 5. Push the branch as a version/milestone checkpoint and open a PR. Describe what changed and how it was verified. Keep the scope of local-only docs (`docs/local/`) out of the PR unless you are a maintainer doing internal investigation.
59
+
60
+ ## Commits & pushes
61
+
62
+ History is part of the review. The maintainer counterpart — tags, clean-tree releases, changelog folding — lives in `docs/00-project-rules.md` §7.
63
+
64
+ ### Conventional, atomic commits
65
+
66
+ - Use [Conventional Commits](https://www.conventionalcommits.org/): `type(optional-scope): summary` in the imperative, about 50–72 characters.
67
+ - Types:
68
+ - `feat:` new capability / route / provider
69
+ - `fix:` bug fix
70
+ - `docs:` documentation (publishable layer)
71
+ - `test:` tests
72
+ - `refactor:` behaviour-preserving cleanup
73
+ - `build:` toolchain, packaging, or committed `lib/` artifacts
74
+ - `ci:` CI workflow
75
+ - `chore:` process-only (including a release bump)
76
+ - Optional scopes such as `M1` / `M3` or a module name are welcome when they help a reviewer.
77
+ - **One coherent concern per commit.** Do not mix docs, build/toolchain and feature/fix work unless they are inseparable (a new capability that cannot be reviewed without its README/changelog note, or a source change that must ship with the `lib/` it generated).
78
+ - Do not rewrite published history. Amend or squash only on an unpushed local commit.
79
+
80
+ ### Before you commit
81
+
82
+ - Build the relevant Docker targets (`check`, then `verify`) and wait until green. Do not commit a failing tree.
83
+ - Commit promptly once checks pass — do not leave a finished, verified change sitting uncommitted next to later work.
84
+ - Generated `lib/` is a committed release artifact (git installs + the CI `git diff --exit-code -- lib` drift gate). Rebuild it and include it in the **same** commit as the source or build-script change that produced it. Do not land stale `lib/` against newer `src/`, and do not land a `lib/`-only commit unless the only change is a verified rebuild with no source delta.
85
+ - Never commit secrets, tokens, credentials, private keys, `.env` files, host-specific paths, or local-only notes (`docs/local/`, `reference/`). See `docs/00-project-rules.md` §0.3.
86
+
87
+ ### Pushing
88
+
89
+ - Push the feature branch as a **checkpoint** at each version or milestone (for example after an M1/M2/M3 slice, or when a version-ready cut is green), not only when the PR is finished.
90
+ - Never force-push (`--force` / `--force-with-lease`) without **explicit maintainer approval**. Default history is append-only, including on your own feature branch once it has been pushed.
91
+ - Open the PR from a pushed checkpoint. Describe what changed and how it was verified.
92
+
93
+ ## Review & merging
94
+
95
+ - At least one other person's approval is needed to merge.
96
+ - A PR that changes public behaviour must not be merged without its README/changelog updates.
97
+ - Do not force-push `main` or a published release tag. Feature-branch force-pushes still need explicit approval (see above).
98
+ - Maintainers run the release loop (`docs/00-project-rules.md` §3–4 and §7) after merging a substantive change: clean working tree, bump version, annotated tag `v<version>`, publish to npm, and keep the GitHub milestone/release updated.
99
+
100
+ ## Reporting security issues
101
+
102
+ Do not open a public issue for a credential or account-safety problem. Follow the compliance/safety policy in `README.md`; for anything sensitive, contact a maintainer directly rather than pasting tokens or credentials anywhere.
103
+
104
+ ## Document layers reminder
105
+
106
+ - **Publishable**: root `README.md` + the community-language READMEs, `INSTALL.md`, `CHANGELOG.md`, `LICENSE`, `NOTICE`, `docs/00-project-rules.md`, `docs/02-architecture.md` + `docs/02-architecture.zh-CN.md`, and other generic `docs/` files. These ship to npm and git — keep them privacy-free.
107
+ - **Local-only**: `docs/local/` and `reference/` are git-ignored and never shipped. Do not reference them from publishable docs.
108
+
109
+ If you are not sure whether a detail is publishable, keep it in the local-only layer or ask a maintainer.
package/INSTALL.md ADDED
@@ -0,0 +1,220 @@
1
+ # 安装与使用 · dsh-coding-subscription-oauth
2
+
3
+ 本仓库原名 **`dsh-grok-build`**。新安装请用:
4
+
5
+ ```bash
6
+ dsh plugin --profile web add github:lninghaha/dsh-coding-subscription-oauth
7
+ ```
8
+
9
+ CLI 新命令是 `dsh-coding-oauth`(旧命令 `dsh-grok-build` 仍可用)。为兼容已有 profile,Cordis id 仍是 `llm-grok-build-oauth`,设置页 HTTP 路径仍是 `/plugins/dsh-grok-build/*`,凭据文件名不变。
10
+
11
+ 第一次公开发布是 **`0.4.1`**。当前推荐 **`0.5.0`**:
12
+
13
+ ```bash
14
+ dsh plugin --profile web add dsh-coding-subscription-oauth@0.5.0
15
+ dsh plugin --profile web update dsh-coding-subscription-oauth
16
+ ```
17
+
18
+ 旧 GitHub 地址会解析到同一条 `main`。
19
+
20
+ ## 前置条件
21
+
22
+ - DeepSeek Harness 0.1.0-rc.6+
23
+ - Node.js 22.19+
24
+ - 需要使用的个人编码订阅;没有 Claude/Google 账号也可以先安装路由
25
+ - 部分网络需要 HTTP/HTTPS 代理
26
+
27
+ ## 安装
28
+
29
+ ```bash
30
+ # 从 GitHub
31
+ dsh plugin --profile web add github:lninghaha/dsh-coding-subscription-oauth
32
+
33
+ # 或本地开发目录
34
+ dsh plugin --profile web add ./dsh-coding-subscription-oauth
35
+
36
+ # Google Antigravity 可选依赖,固定版本
37
+ dsh plugin --profile web add dsh-agy@0.1.2
38
+ ```
39
+
40
+ 安装后重启现有 dsh web 进程;不要另起一个端口相同的服务器。
41
+
42
+ 本地 API 网关默认关闭。需要时在 profile 里打开(只绑 loopback):
43
+
44
+ ```yaml
45
+ gateway:
46
+ enabled: true
47
+ bind: 127.0.0.1
48
+ port: 18080
49
+ ```
50
+
51
+ 或在 Settings → Coding OAuth → Local API gateway 打开。Bearer key 存在 `$DSH_HOME/.coding-oauth-gateway.json`。不要绑定 `0.0.0.0`。
52
+
53
+ ## Antigravity 安全配置
54
+
55
+ `dsh-agy@0.1.2` 的 `/agy` standalone dashboard 没有自己的认证,并包含凭据导出接口。Web 服务带 trusted-host 或反向代理时,建议在 profile 最终 `cordis.patch.yml` 禁用该 dashboard:
56
+
57
+ ```yaml
58
+ - id: dsh-agy-web
59
+ disabled: true
60
+ ```
61
+
62
+ 这不会禁用 `agy` LLM route 或 profile 内的 `dsh-agy` CLI。
63
+
64
+ Google OAuth 后续可用:
65
+
66
+ ```bash
67
+ NODE_USE_ENV_PROXY=1 \
68
+ HTTPS_PROXY=http://127.0.0.1:7890 \
69
+ dsh plugin --profile web exec dsh-agy login --headless
70
+ ```
71
+
72
+ 仅在当前网络确实需要代理时设置 `NODE_USE_ENV_PROXY` / `HTTPS_PROXY`;其他环境直接执行最后一行即可。不要把 Google credential export 粘贴到聊天或日志。
73
+
74
+ ## 代理配置
75
+
76
+ 推荐在 profile 的最终 patch 里配置常驻服务:
77
+
78
+ ```yaml
79
+ - id: llm-grok-build-oauth
80
+ config:
81
+ proxy: http://127.0.0.1:7890
82
+ proxyKimi: false
83
+ ```
84
+
85
+ 解析优先级:`config.proxy` → `CODING_OAUTH_PROXY` → `GROK_BUILD_PROXY` → `HTTPS_PROXY` / `HTTP_PROXY`。
86
+
87
+ 默认进入代理的域名组:
88
+
89
+ - xAI/Grok Build
90
+ - OpenAI Codex
91
+ - Claude/Anthropic
92
+ - Google OAuth/Cloud Code
93
+
94
+ Kimi Code 中国流量默认直连;只有 `proxyKimi: true` 才代理。
95
+
96
+ ## 弹性重试
97
+
98
+ OAuth access token 会在本地记录过期时间前 5 分钟主动刷新。服务端若仍以 401/403 拒绝一个本地尚未过期的令牌,插件会把凭据 `expires` 回写到过去,重试的 step 先刷新再发请求。瞬时故障(429/5xx/超时/网络)和 AUTH 默认最多重试 2 次(500 ms → 10 s,10% jitter)。配额耗尽和 refresh token 失效不重试。
99
+
100
+ 部署级覆盖(可选):
101
+
102
+ ```yaml
103
+ - id: llm-grok-build-oauth
104
+ config:
105
+ retryPolicy:
106
+ mode: normal
107
+ maxRetries: 2
108
+ retryableCodes: [EMPTY_RESPONSE, RATE_LIMIT, SERVER, TIMEOUT, TRANSPORT, AUTH]
109
+ backoff: { initialDelayMs: 500, maxDelayMs: 10000, jitterRatio: 0.1 }
110
+ ```
111
+
112
+ ## 登录
113
+
114
+ ### 设置页
115
+
116
+ 打开 **设置 → 编码 OAuth**:
117
+
118
+ - **Grok Build**:授权码或设备码
119
+ - **OpenAI Codex**:远程部署推荐设备码;浏览器 PKCE 支持粘贴 redirect URL
120
+ - **Kimi Code**:设备码
121
+ - **Claude Code**:浏览器 PKCE,远程访问时粘贴完整 localhost redirect URL
122
+
123
+ 设置页会**只读发现**白名单内的官方 Grok / Codex / Kimi / Claude CLI OAuth 文件。同步是显式的单向**拉取**(不是自动导入):发现 → 预览 → 冲突/指纹核对 → 确认覆盖。官方 CLI 文件从不被写入。读取会拒绝符号链接、非普通文件、非属主文件、组/其他人可读,以及超大文档(`O_NOFOLLOW`)。预览票据一次性、五分钟过期、最多 32 张。CLI 的 `dsh-coding-oauth import` 仍只支持 Grok。
124
+
125
+ 登录过程只交换授权 code;状态接口不返回 access/refresh token。
126
+
127
+ ### 可选能力
128
+
129
+ 设置页的七项订阅能力开关默认全部关闭,打开后立即生效(无需重启):`codexSearch`、`codexImages`、`codexImageEdits`、`codexUsage`、`codexFast`、`grokImagineImage`、`grokImagineVideo`。
130
+
131
+ 数值控制为 `searchResults`(1–20,默认 5)、`imageCount`(1–4,默认 1)、`videoArtifactTtlMs`(1 小时–7 天,默认 7 天;界面以 1–168 小时显示)。降低视频保留时间会立即缩短并清理已有产物;提高只影响之后生成的产物。管理员可在插件配置的 `capabilities` 下提供不含秘密的 composition 默认值;`coding-subscription-oauth` 设置区中的用户值会覆盖该 base,省略时所有开关仍默认关闭。
132
+
133
+ `codex-oauth-fast` 仅在最新一次 live catalog 标明至少有一个 `priority` 可用模型后才会出现。请求发送 `service_tier: priority` 和路由提示;界面写 **已请求 Fast**,不保证延迟或上游兑现。Codex 搜索/用量/图像是需打开的私有 `chatgpt.com/backend-api` 端点;图像固定 `gpt-image-2`;编辑只接受当前会话顶层、本会话持有的附件。
134
+
135
+ 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 路由提供。
136
+
137
+ ### CLI
138
+
139
+ ```bash
140
+ # Grok(`dsh-grok-build` 仍是同一条命令的别名)
141
+ dsh-coding-oauth login
142
+ dsh-coding-oauth login --pkce
143
+ dsh-coding-oauth import
144
+
145
+ # Codex / Kimi / Claude
146
+ dsh-coding-oauth login codex --device-auth
147
+ dsh-coding-oauth login codex --browser
148
+ dsh-coding-oauth login kimi
149
+ dsh-coding-oauth login claude
150
+
151
+ # 状态/登出
152
+ dsh-coding-oauth status all
153
+ dsh-coding-oauth logout kimi
154
+ ```
155
+
156
+ ## 模型路由
157
+
158
+ - `grok-build/<model>`
159
+ - `codex-oauth/<model>`
160
+ - `codex-oauth-fast/<model>`(可选;仅在最新 live catalog 标明 `priority` 可用后出现,界面为 已请求 Fast)
161
+ - `kimi-code-oauth/<model>`
162
+ - `claude-code-oauth/<model>`
163
+ - `agy/<model>`(安装 dsh-agy 后)
164
+
165
+ 这些别名专门避免与已有的 `xai`、`openai`、`kimi-coding` API-key routes 冲突。插件不会修改现有默认模型设置。未认证的 OAuth route 不向模型选择器返回任何模型;认证后供应商名显示为 `(OAuth)`,登录/登出会立即触发目录刷新。
166
+
167
+ ## 凭据与缓存
168
+
169
+ OAuth 凭据:
170
+
171
+ ```text
172
+ $DSH_HOME/.grok-build-auth.json
173
+ $DSH_HOME/.codex-oauth-auth.json
174
+ $DSH_HOME/.kimi-code-oauth-auth.json
175
+ $DSH_HOME/.claude-code-oauth-auth.json
176
+ ```
177
+
178
+ 均为 `0600`、原子写、文件锁保护。模型缓存为对应的 `*-models.json`,不含 token。Grok Imagine 使用 DSH 凭据引用 `XAI_API_KEY`,与上述 OAuth 文件分离;视频产物存入 `$DSH_HOME/.dsh-coding-subscription-oauth-media/`(目录 `0700`、文件 `0600`),按保留设置自动清理。
179
+
180
+ ## 卸载
181
+
182
+ ```bash
183
+ dsh plugin --profile web remove dsh-agy dsh-coding-subscription-oauth
184
+ rm -f ~/.dsh/.grok-build-auth.json ~/.dsh/.codex-oauth-auth.json \
185
+ ~/.dsh/.kimi-code-oauth-auth.json ~/.dsh/.claude-code-oauth-auth.json
186
+ rm -f ~/.dsh/.grok-build-models.json ~/.dsh/.codex-oauth-models.json \
187
+ ~/.dsh/.kimi-code-oauth-models.json ~/.dsh/.claude-code-oauth-models.json
188
+ ```
189
+
190
+ 只有在确认不再需要账号后才删除凭据文件。
191
+
192
+ ## 部署验收
193
+
194
+ ```bash
195
+ pnpm run verify:deployed
196
+
197
+ DSH_RESTORE_PROVIDER=openai \
198
+ DSH_RESTORE_MODEL=gpt-5.6-sol \
199
+ DSH_RESTORE_REASONING=max \
200
+ pnpm run smoke:deployed
201
+ ```
202
+
203
+ 第一条命令验证真实模型目录的认证门禁和 `(OAuth)` 标签。第二条会通过运行中的 DSH 分别执行 Codex/Kimi 的 tool-call 与第二个用户 turn(覆盖 `INVALID_REPLAY_STATE` 回归),随后恢复显式指定的默认模型并归档测试会话;为避免覆盖现有默认设置,不提供 `DSH_RESTORE_*` 时脚本拒绝运行。
204
+
205
+ ## 故障排查
206
+
207
+ | 现象 | 处理 |
208
+ |---|---|
209
+ | 还在搜 / 装着 `dsh-grok-build` | 仓库已更名为 `dsh-coding-subscription-oauth`;旧 GitHub 地址仍跟踪同一条 `main`。新安装请用新名 |
210
+ | Codex localhost callback 打不开 | 改用设备码,或把完整 redirect URL 粘贴回设置页 |
211
+ | Claude localhost callback 在远端浏览器 | 把完整 redirect URL 粘贴回设置页 |
212
+ | Kimi 401/403 | 重新登录并确认 Kimi Code 会员有效;不要改成 moonshot.cn OAuth |
213
+ | OAuth refresh failed | 对应账号重新登录;插件不会回退到其他账号或 API key |
214
+ | 模型 route 重复 | 保留本插件的 `*-oauth` alias,移除冲突的第三方 OAuth 插件 |
215
+ | Antigravity 页面 404 | 安全配置默认禁用了 `dsh-agy-web`;使用 CLI |
216
+ | Google/Claude/OpenAI 网络不可达 | 检查插件 scoped proxy;不要重启或修改系统网络服务 |
217
+
218
+ ## 合规提示
219
+
220
+ 订阅 OAuth 接入第三方 harness 可能违反或触及供应商服务条款。仅供个人账号使用,自行承担配额和账号风险;商用请使用官方 API-key 通道。
package/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ Copyright 2026 dsh-xai contributors
8
+
9
+ Licensed under the Apache License, Version 2.0 (the "License");
10
+ you may not use this file except in compliance with the License.
11
+ You may obtain a copy of the License at
12
+
13
+ http://www.apache.org/licenses/LICENSE-2.0
14
+
15
+ Unless required by applicable law or agreed to in writing, software
16
+ distributed under the License is distributed on an "AS IS" BASIS,
17
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ See the License for the specific language governing permissions and
19
+ limitations under the License.
package/NOTICE ADDED
@@ -0,0 +1,11 @@
1
+ NOTICE
2
+ ======
3
+
4
+ dsh-coding-subscription-oauth (formerly dsh-grok-build) — coding-subscription OAuth for DeepSeek Harness
5
+ Copyright 2026 lninghaha
6
+
7
+ This product includes software developed by the dsh-xai project
8
+ (https://github.com/MirDie/dsh-xai), licensed under the Apache License,
9
+ Version 2.0. Portions of src/store.ts, src/session.ts, src/grok-import.ts,
10
+ src/redact.ts, src/invariant.ts, src/adapter.ts, src/auth.ts, src/bin.ts and
11
+ the build scaffolding are derived from that work.