dsh-grok-subscription 2.0.4 → 2.0.5
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 +7 -0
- package/README.en.md +4 -2
- package/README.md +4 -2
- package/docs/guide.en.md +5 -3
- package/docs/guide.zh-CN.md +5 -3
- package/lib/client.js +2 -2
- package/lib/index.js +18 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.5 — 2026-10-01
|
|
4
|
+
|
|
5
|
+
- Fix **every conversation failing with HTTP 426** once the subscription proxy started requiring `x-grok-client-version` `1.0.13` or later. On a machine with no grok CLI — the normal case since 2.0.4 — the plugin advertised the hardcoded `1.0.5`, and `POST /v1/responses` answered `Your Grok CLI version (1.0.5) is outdated`. Settings, the model list and the quota card kept working, because `GET /v1/models-v2` and `GET /v1/billing` are not gated. Fixes #1.
|
|
6
|
+
- The value sent when no current CLI release is known is now `99.0.0`. Measured against the live proxy on 2026-10-01, the check is a **minimum with no upper bound**: `1.0.5` and the prerelease `1.0.13-rc1` are 426, and `1.0.13`, `1.0.14`, `1.1.0`, `2.0.0` and `99.0.0` are 200. A fallback can only be too old, which is the failure this release hit, so it stays far ahead of the published minimum instead of tracking each CLI release. `User-Agent` remains `grok-shell/` plus the same version.
|
|
7
|
+
- A `version.json` that is missing, unreadable, not a `MAJOR.MINOR.PATCH` release, or older than the fallback no longer lowers the header. A release at or above the fallback is still advertised. `DSH_GROK_CLIENT_VERSION` still wins exactly as set, including a value the proxy would reject.
|
|
8
|
+
- That override cannot live in `~/.dsh/.env`. `dsh-app-boot` refuses every `DSH_`-prefixed name, so it has to be exported in the environment that launches DSH, followed by a full restart. Both guides now have a troubleshooting row for the 426.
|
|
9
|
+
|
|
3
10
|
## 2.0.4 — 2026-09-30
|
|
4
11
|
|
|
5
12
|
- **Sign-in and renewal no longer run the grok command.** Settings requests a device code from `https://auth.x.ai`, shows the link and one-time code, and writes the session into `${GROK_HOME:-~/.grok}/auth.json` after the browser confirms it. A token near expiry is renewed with the refresh token at the same token endpoint. The official CLI binary is not required, and an `auth.json` already written by `grok login` can still be loaded with **Read saved session**.
|
package/README.en.md
CHANGED
|
@@ -61,13 +61,13 @@ Pick a Grok model your account can use, adjust reasoning effort as needed, and s
|
|
|
61
61
|
<details>
|
|
62
62
|
<summary>Check the version / pin one / fall back when the UI install fails</summary>
|
|
63
63
|
|
|
64
|
-
**Settings → Plugins** lists the installed plugins and their versions, and the plugin's own **Settings → Grok Subscription** page shows a version card. To pin a version, put the full `package@version` in the install field, for example `dsh-grok-subscription@2.0.
|
|
64
|
+
**Settings → Plugins** lists the installed plugins and their versions, and the plugin's own **Settings → Grok Subscription** page shows a version card. To pin a version, put the full `package@version` in the install field, for example `dsh-grok-subscription@2.0.5`.
|
|
65
65
|
|
|
66
66
|
If the UI install fails (an unusual profile directory, say), the equivalent runs against the desktop profile itself (pnpm ≥ 11):
|
|
67
67
|
|
|
68
68
|
```sh
|
|
69
69
|
cd "$HOME/.dsh/profiles/desktop" # Windows: cd "$env:USERPROFILE\.dsh\profiles\desktop"
|
|
70
|
-
pnpm add --save-exact --config.minimumReleaseAge=0 dsh-grok-subscription@2.0.
|
|
70
|
+
pnpm add --save-exact --config.minimumReleaseAge=0 dsh-grok-subscription@2.0.5
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
`dsh plugin --profile desktop …` is refused: the Electron application owns that profile exclusively. Sign-in and troubleshooting are in the [full user guide](docs/guide.en.md).
|
|
@@ -133,6 +133,8 @@ Restart DSH afterwards. Removal does not delete other plugins, the whole profile
|
|
|
133
133
|
|
|
134
134
|
**Sign-in or requests time out?** Check connectivity from the DSH host to account and subscription services, including its launch-time proxy settings. Network issues, authentication, or service errors can cause failures; do not assume the quota is exhausted. See [Troubleshooting](docs/guide.en.md#troubleshooting).
|
|
135
135
|
|
|
136
|
+
**A message fails with HTTP 426 and says the CLI is outdated?** Update to the current release and restart completely. Settings and the model list can still look healthy, because only generation checks the client version. See [Troubleshooting](docs/guide.en.md#troubleshooting).
|
|
137
|
+
|
|
136
138
|
**Images still unavailable after updating?** Fully restart the desktop app, check the model's image support, and check that **Active path** in Settings reads **official pi-ai** with attachment capability available. An **unavailable** row means the host has no pi-ai adapter.
|
|
137
139
|
|
|
138
140
|
## Scope and support
|
package/README.md
CHANGED
|
@@ -61,13 +61,13 @@
|
|
|
61
61
|
<details>
|
|
62
62
|
<summary>确认版本 / 固定版本 / 界面安装失败时的兜底</summary>
|
|
63
63
|
|
|
64
|
-
**设置 → 插件** 会列出已安装插件与版本,插件自己的 **设置 → Grok 订阅** 页也有版本卡片。要固定版本,在安装框里填入完整的 `包名@版本`,例如 `dsh-grok-subscription@2.0.
|
|
64
|
+
**设置 → 插件** 会列出已安装插件与版本,插件自己的 **设置 → Grok 订阅** 页也有版本卡片。要固定版本,在安装框里填入完整的 `包名@版本`,例如 `dsh-grok-subscription@2.0.5`。
|
|
65
65
|
|
|
66
66
|
界面安装失败时(例如 profile 目录权限异常),可以对桌面版 profile 手动执行等价操作(pnpm ≥ 11):
|
|
67
67
|
|
|
68
68
|
```sh
|
|
69
69
|
cd "$HOME/.dsh/profiles/desktop" # Windows: cd "$env:USERPROFILE\.dsh\profiles\desktop"
|
|
70
|
-
pnpm add --save-exact --config.minimumReleaseAge=0 dsh-grok-subscription@2.0.
|
|
70
|
+
pnpm add --save-exact --config.minimumReleaseAge=0 dsh-grok-subscription@2.0.5
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
`dsh plugin --profile desktop …` 会被拒绝:桌面版 profile 由 Electron 应用独占。登录方式与故障排查见 [完整使用指南](docs/guide.zh-CN.md)。
|
|
@@ -129,6 +129,8 @@ pnpm add --save-exact --config.minimumReleaseAge=0 dsh-grok-subscription@2.0.4
|
|
|
129
129
|
|
|
130
130
|
**登录或请求超时?** 检查 DSH 所在机器能否连接账号与订阅服务,以及启动环境的代理设置。网络、登录状态和服务端异常都可能导致失败,不要直接认定为额度耗尽。见 [故障排查](docs/guide.zh-CN.md#故障排查)。
|
|
131
131
|
|
|
132
|
+
**发一条消息就返回 426,说 CLI 版本过旧?** 更新到当前版本并完全重启。设置页和模型列表仍可能正常,因为只有生成接口检查客户端版本。见 [故障排查](docs/guide.zh-CN.md#故障排查)。
|
|
133
|
+
|
|
132
134
|
**更新后不能带图?** 完整重启桌面应用,检查模型是否在图片支持列表,以及设置页的「运行通路」是否显示**官方 pi-ai** 且附件能力可用。若显示「不可用」,说明宿主缺少 pi-ai 适配器。
|
|
133
135
|
|
|
134
136
|
## 边界与支持
|
package/docs/guide.en.md
CHANGED
|
@@ -8,7 +8,7 @@ For quick setup, see the [README](../README.en.md#install). This guide covers de
|
|
|
8
8
|
|
|
9
9
|
You need the DeepSeek Harness desktop app and an account with Grok Build access. The grok command is not required. The plugin declares Node.js `^22.19.0 || >=24.0.0`; DSH peers use `>=0.1.5-rc.2 <0.3.0-0`, which spans the whole 0.1 and 0.2 lines. See [package.json](../package.json) for the full requirements. Declared compatibility is not a claim that every version has passed live verification.
|
|
10
10
|
|
|
11
|
-
**Install:** in the desktop app open **Settings → Plugins**, type the package name `dsh-grok-subscription` into the install field, and install it. Then **quit and restart the desktop app completely**; refreshing the page alone does not reload the Host adapter. To pin a version, put the full `package@version` in that field, for example `dsh-grok-subscription@2.0.
|
|
11
|
+
**Install:** in the desktop app open **Settings → Plugins**, type the package name `dsh-grok-subscription` into the install field, and install it. Then **quit and restart the desktop app completely**; refreshing the page alone does not reload the Host adapter. To pin a version, put the full `package@version` in that field, for example `dsh-grok-subscription@2.0.5`.
|
|
12
12
|
|
|
13
13
|
**The plugin depends on the host's own pi-ai adapter.** From 2.0.0 the `grok-build` route is served entirely by the host's `@deepseek-ai/dsh-llm-pi-ai` / `@earendil-works/pi-ai`, which every DSH installation carries (`@deepseek-ai/dsh` → `dsh-base` → `dsh-llm-pi-ai`, with the `llm-pi-ai` row mounted unconditionally). If those packages cannot be resolved from the DSH installation, the plugin registers no route at all and **Active path** in Settings reads **unavailable**.
|
|
14
14
|
|
|
@@ -16,7 +16,7 @@ If the UI install fails (an unusual profile directory, say), the equivalent runs
|
|
|
16
16
|
|
|
17
17
|
```sh
|
|
18
18
|
cd "$HOME/.dsh/profiles/desktop" # Windows: cd "$env:USERPROFILE\.dsh\profiles\desktop"
|
|
19
|
-
pnpm add --save-exact --config.minimumReleaseAge=0 dsh-grok-subscription@2.0.
|
|
19
|
+
pnpm add --save-exact --config.minimumReleaseAge=0 dsh-grok-subscription@2.0.5
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
`dsh plugin --profile desktop …` is refused: the Electron application owns that profile exclusively.
|
|
@@ -75,6 +75,8 @@ For prefix caching, the plugin pins one stable `prompt_cache_key` per DSH sessio
|
|
|
75
75
|
|
|
76
76
|
**Chat or usage returns `401`.** If automatic renewal fails, sign in again from Settings. Do not repeatedly paste an old token.
|
|
77
77
|
|
|
78
|
+
**Chat returns HTTP 426 saying the Grok CLI is outdated.** Generation (`POST /v1/responses`) requires `x-grok-client-version` of at least `1.0.13`. The model catalog and billing endpoints are not checked, so Settings, the model list and the quota card can look fine while every message fails. `2.0.4` and earlier advertised `1.0.5` when the grok command was absent and `~/.grok/version.json` could not be read. Current releases advertise the built-in fallback — a release above that published minimum; a prerelease such as `1.0.13-rc1` does not count — unless an installed CLI `version.json` is itself a release at least that high. A stale `version.json` no longer pulls the header back down. To pin it yourself, set `DSH_GROK_CLIENT_VERSION` in the **environment that launches DSH** (a `MAJOR.MINOR.PATCH` release, at least `1.0.13`) and restart completely. Do not put it in `~/.dsh/.env`: names with the `DSH_` prefix are refused by the bootstrap layer.
|
|
79
|
+
|
|
78
80
|
**Images rejected.** Check the supported IDs, confirm **Active path** reads **official pi-ai** with attachment capability available, and fully restart the desktop app after updating.
|
|
79
81
|
|
|
80
82
|
**Auth-file permission error.** Check the actual path, owner, symlink status, and permissions. `chmod 600` fixes permission bits only.
|
|
@@ -93,7 +95,7 @@ In the desktop app the `desktop` profile is owned exclusively by the Electron ap
|
|
|
93
95
|
|
|
94
96
|
```sh
|
|
95
97
|
cd "$HOME/.dsh/profiles/desktop" # Windows: cd "$env:USERPROFILE\.dsh\profiles\desktop"
|
|
96
|
-
pnpm add --save-exact --config.minimumReleaseAge=0 dsh-grok-subscription@2.0.
|
|
98
|
+
pnpm add --save-exact --config.minimumReleaseAge=0 dsh-grok-subscription@2.0.5
|
|
97
99
|
```
|
|
98
100
|
|
|
99
101
|
Then quit and restart the desktop app completely. After a successful update the profile's `package.json` dependency should show the target version while its `dsh.profile.bundles` entry is unchanged. Refreshing the browser is not enough: without a Host restart the old version keeps loading.
|
package/docs/guide.zh-CN.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
需要 DeepSeek Harness 桌面版,以及当前具有 Grok Build 使用资格的订阅账号。不需要安装 grok 命令。插件的 Node.js 要求为 `^22.19.0 || >=24.0.0`,DSH peer 声明以 [package.json](../package.json) 为准;其中 DSH 依赖使用 `>=0.1.5-rc.2 <0.3.0-0`,覆盖 0.1 与 0.2 全线。声明范围不等于所有版本都已经过实机验证。
|
|
10
10
|
|
|
11
|
-
**安装:** 在桌面版打开 **设置 → 插件**,在安装输入框里填入包名 `dsh-grok-subscription` 并安装,然后**完全退出并重启桌面应用**。仅刷新页面不会重新加载 Host 中的适配器。需要可重复安装时,填入完整的 `包名@版本`,例如 `dsh-grok-subscription@2.0.
|
|
11
|
+
**安装:** 在桌面版打开 **设置 → 插件**,在安装输入框里填入包名 `dsh-grok-subscription` 并安装,然后**完全退出并重启桌面应用**。仅刷新页面不会重新加载 Host 中的适配器。需要可重复安装时,填入完整的 `包名@版本`,例如 `dsh-grok-subscription@2.0.5`。
|
|
12
12
|
|
|
13
13
|
**插件依赖宿主自带的 pi-ai 适配器。** 从 2.0.0 起,`grok-build` 路由完全由宿主的 `@deepseek-ai/dsh-llm-pi-ai` / `@earendil-works/pi-ai` 服务;DSH 的任何安装方式都带有它们(`@deepseek-ai/dsh` → `dsh-base` → `dsh-llm-pi-ai`,且 `llm-pi-ai` 行无条件挂载)。这两个包无法从 DSH 安装目录解析时,插件不会注册任何路由,设置页的「运行通路」显示**不可用**。
|
|
14
14
|
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
```sh
|
|
18
18
|
cd "$HOME/.dsh/profiles/desktop" # Windows: cd "$env:USERPROFILE\.dsh\profiles\desktop"
|
|
19
|
-
pnpm add --save-exact --config.minimumReleaseAge=0 dsh-grok-subscription@2.0.
|
|
19
|
+
pnpm add --save-exact --config.minimumReleaseAge=0 dsh-grok-subscription@2.0.5
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
`dsh plugin --profile desktop …` 会被直接拒绝:桌面版 profile 由 Electron 应用独占。
|
|
@@ -75,6 +75,8 @@ grok-4.6
|
|
|
75
75
|
|
|
76
76
|
**聊天或用量返回 `401`。** 自动续期失败时,在设置页重新登录。不要反复粘贴旧 token。
|
|
77
77
|
|
|
78
|
+
**对话返回 HTTP 426,提示 Grok CLI 版本过旧。** 生成接口(`POST /v1/responses`)要求 `x-grok-client-version` 不低于 `1.0.13`。模型目录和额度接口不检查这项,所以设置页、模型列表和用量卡片可以一切正常,只有发消息失败。`2.0.4` 及更早在没有 grok 命令、也读不到 `~/.grok/version.json` 时会声明 `1.0.5`。当前版本在没有不低于内置回退值的 CLI 正式版本时,改发该回退值(高于已公布的下限;`1.0.13-rc1` 这类预发布号不算)。过旧的 `version.json` 不会再把请求头拉低。仍要自己指定时,在**启动 DSH 的进程环境**里设置 `DSH_GROK_CLIENT_VERSION`(`MAJOR.MINOR.PATCH` 正式版本,且不低于 `1.0.13`),然后完全重启。不要写进 `~/.dsh/.env`:`DSH_*` 会被启动层拒绝。
|
|
79
|
+
|
|
78
80
|
**图片被拒绝。** 对照图片支持列表,确认设置页「运行通路」显示**官方 pi-ai** 且附件能力可用,并在更新后完整重启桌面应用。
|
|
79
81
|
|
|
80
82
|
**文件权限错误。** 检查 auth 文件的真实路径、所有者、是否为符号链接以及权限;`chmod 600` 仅解决权限位问题。
|
|
@@ -93,7 +95,7 @@ grok-4.6
|
|
|
93
95
|
|
|
94
96
|
```sh
|
|
95
97
|
cd "$HOME/.dsh/profiles/desktop" # Windows: cd "$env:USERPROFILE\.dsh\profiles\desktop"
|
|
96
|
-
pnpm add --save-exact --config.minimumReleaseAge=0 dsh-grok-subscription@2.0.
|
|
98
|
+
pnpm add --save-exact --config.minimumReleaseAge=0 dsh-grok-subscription@2.0.5
|
|
97
99
|
```
|
|
98
100
|
|
|
99
101
|
然后完全退出并重启桌面版。更新成功后该 profile 的 `package.json` 里依赖应变为目标版本,`dsh.profile.bundles` 条目保持不变。仅刷新网页不够:Host 未重启时仍会加载旧版本。
|
package/lib/client.js
CHANGED
|
@@ -39,7 +39,7 @@ var import_react2 = require("react");
|
|
|
39
39
|
var zh = {
|
|
40
40
|
nav: "Grok \u8BA2\u9605",
|
|
41
41
|
title: "Grok \u8BA2\u9605",
|
|
42
|
-
subtitle: "\u7528 SuperGrok / X Premium\uFF08Grok Build\uFF09\u4F1A\u8BDD\uFF0C\u800C\u4E0D\u662F XAI_API_KEY\u3002\xB7 2.0.
|
|
42
|
+
subtitle: "\u7528 SuperGrok / X Premium\uFF08Grok Build\uFF09\u4F1A\u8BDD\uFF0C\u800C\u4E0D\u662F XAI_API_KEY\u3002\xB7 2.0.5",
|
|
43
43
|
signedIn: "\u5DF2\u767B\u5F55",
|
|
44
44
|
signedOut: "\u672A\u767B\u5F55",
|
|
45
45
|
account: "\u8D26\u6237",
|
|
@@ -122,7 +122,7 @@ var zh = {
|
|
|
122
122
|
var en = {
|
|
123
123
|
nav: "Grok Subscription",
|
|
124
124
|
title: "Grok Subscription",
|
|
125
|
-
subtitle: "Use a SuperGrok / X Premium (Grok Build) session, not XAI_API_KEY. \xB7 2.0.
|
|
125
|
+
subtitle: "Use a SuperGrok / X Premium (Grok Build) session, not XAI_API_KEY. \xB7 2.0.5",
|
|
126
126
|
signedIn: "Signed in",
|
|
127
127
|
signedOut: "Signed out",
|
|
128
128
|
account: "Account",
|
package/lib/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var TOKEN_AUTH_VALUE = "xai-grok-cli";
|
|
|
14
14
|
var CLIENT_IDENTIFIER_HEADER = "x-grok-client-identifier";
|
|
15
15
|
var CLIENT_VERSION_HEADER = "x-grok-client-version";
|
|
16
16
|
var CLIENT_IDENTIFIER = "grok-shell";
|
|
17
|
-
var CLIENT_VERSION_FALLBACK = "
|
|
17
|
+
var CLIENT_VERSION_FALLBACK = "99.0.0";
|
|
18
18
|
var API_KEY_SCOPE = "xai::api_key";
|
|
19
19
|
var XAI_OAUTH_ISSUER = "https://auth.x.ai";
|
|
20
20
|
var GROK_OIDC_CLIENT_ID = "b1a00492-073a-47ea-816f-4c329264a828";
|
|
@@ -343,19 +343,33 @@ function parseClientVersion(document) {
|
|
|
343
343
|
}
|
|
344
344
|
return void 0;
|
|
345
345
|
}
|
|
346
|
+
function releaseAtLeast(version, minimum) {
|
|
347
|
+
const parse = (value) => {
|
|
348
|
+
const match = /^v?(\d+)\.(\d+)\.(\d+)$/.exec(typeof value === "string" ? value.trim() : "");
|
|
349
|
+
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : void 0;
|
|
350
|
+
};
|
|
351
|
+
const left = parse(version);
|
|
352
|
+
const right = parse(minimum);
|
|
353
|
+
if (!left || !right) return false;
|
|
354
|
+
for (let index = 0; index < 3; index += 1) {
|
|
355
|
+
if (left[index] !== right[index]) return left[index] > right[index];
|
|
356
|
+
}
|
|
357
|
+
return true;
|
|
358
|
+
}
|
|
346
359
|
function readClientVersion(env = process.env, options = {}) {
|
|
347
360
|
if (typeof env.DSH_GROK_CLIENT_VERSION === "string" && env.DSH_GROK_CLIENT_VERSION.trim()) {
|
|
348
361
|
return env.DSH_GROK_CLIENT_VERSION.trim();
|
|
349
362
|
}
|
|
363
|
+
const fallback = options.fallback ?? CLIENT_VERSION_FALLBACK;
|
|
350
364
|
const path = options.path ?? versionJsonPath(env);
|
|
351
365
|
const exists = options.exists ?? existsSync;
|
|
352
366
|
const read = options.read ?? ((target) => readFileSync2(target, "utf8"));
|
|
353
|
-
if (!exists(path)) return
|
|
367
|
+
if (!exists(path)) return fallback;
|
|
354
368
|
try {
|
|
355
369
|
const parsed = parseClientVersion(JSON.parse(read(path)));
|
|
356
|
-
return parsed
|
|
370
|
+
return parsed && releaseAtLeast(parsed, fallback) ? parsed : fallback;
|
|
357
371
|
} catch {
|
|
358
|
-
return
|
|
372
|
+
return fallback;
|
|
359
373
|
}
|
|
360
374
|
}
|
|
361
375
|
function fingerprintHeaders(options = {}) {
|