dsh-grok-subscription 1.1.0 → 1.1.1

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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.1 — 2026-09-28
4
+
5
+ - Fix **Update plugin** failing in the desktop app. The update built its command from `process.argv[1]`, which is the entry script of whichever process loaded the plugin — the `dsh` CLI only when the host *is* the CLI. The desktop app loads plugins inside `@deepseek-ai/dsh-desktop-host`, so that argument was the desktop host entry and the update relaunched the application with `plugin …` as script arguments instead of installing anything. The version check kept working, so the update button appeared to run and then reported failure.
6
+ - Install updates into the owning profile with pnpm directly, because `dsh plugin --profile desktop` is refused outright: `profile "desktop" is managed exclusively by the Electron application`. The bundled pnpm entry is located by file name in the host's own launch arguments, with the runtime directory carrying the `@deepseek-ai/dsh` package as the fallback, so `PATH` never decides which package manager runs.
7
+ - Pin the install (`--save-exact`) and disable pnpm's release-age gate (`--config.minimumReleaseAge=0`), which would otherwise quietly keep the installed version for a release younger than 24 hours — exactly the release this button exists to fetch.
8
+ - Read the installed manifest back and compare it with the requested version before reporting success, so an update that installs nothing is reported as a failure rather than a success.
9
+ - No model-routing, authentication, proxy, or quota behavior changes. Restart DSH fully after updating so the new version loads.
10
+
3
11
  ## 1.1.0 — 2026-09-28
4
12
 
5
13
  - Add the original Comet Navigator mascot and align the Chinese/English homepages around features, installation, daily use, screenshots, and maintenance.
package/README.en.md CHANGED
@@ -130,6 +130,8 @@ dsh plugin --profile web add dsh-grok-subscription@latest
130
130
 
131
131
  For a GitHub-source install, use `dsh plugin --profile web update dsh-grok-subscription`. For a local `link:` install, pull and rebuild the checkout instead of replacing its development link.
132
132
 
133
+ The desktop app owns its `desktop` profile exclusively, so `dsh plugin --profile desktop …` is refused there. The desktop **Update plugin** button therefore installs the exact version inside that profile directory with DSH's own bundled pnpm; before `1.1.1` that button always failed in the desktop app. Manual steps: [Updates and sign-out](docs/guide.en.md#updates-and-sign-out).
134
+
133
135
  **Uninstall:**
134
136
 
135
137
  ```sh
package/README.md CHANGED
@@ -130,6 +130,8 @@ dsh plugin --profile web add dsh-grok-subscription@latest
130
130
 
131
131
  GitHub 来源安装可使用 `dsh plugin --profile web update dsh-grok-subscription`;本地 `link:` 安装应拉取对应仓库并重新构建,不要替换开发链接。
132
132
 
133
+ 桌面版由 Electron 应用独占 `desktop` profile,`dsh plugin --profile desktop …` 会被拒绝,因此桌面版的「更新插件」由插件自己在该 profile 目录中用 DSH 自带的 pnpm 安装精确版本;`1.1.1` 之前该按钮在桌面版必然失败,手动步骤见[更新与登出](docs/guide.zh-CN.md#更新与登出)。
134
+
133
135
  **卸载:**
134
136
 
135
137
  ```sh
package/docs/guide.en.md CHANGED
@@ -18,7 +18,7 @@ dsh plugin --profile web list dsh-grok-subscription --depth 0
18
18
  For reproducibility, pin a published version, for example:
19
19
 
20
20
  ```sh
21
- dsh plugin --profile web add dsh-grok-subscription@1.1.0
21
+ dsh plugin --profile web add dsh-grok-subscription@1.1.1
22
22
  ```
23
23
 
24
24
  **Install from GitHub:**
@@ -128,6 +128,15 @@ That task makes a real model request and uses the selected service's quota; it i
128
128
 
129
129
  For npm installs, update in Settings or run `dsh plugin --profile web add dsh-grok-subscription@latest`. For GitHub-source installs, run `dsh plugin --profile web update dsh-grok-subscription`. For local links, pull, test, and rebuild the checkout. Restart DSH afterwards.
130
130
 
131
+ In the desktop app the `desktop` profile is owned exclusively by the Electron application, and `dsh plugin --profile desktop …` is refused outright (`profile "desktop" is managed exclusively by the Electron application`), so the desktop app can only be updated by the plugin itself. From 1.1.1 the **Update plugin** button installs the exact version inside that profile directory with DSH's own bundled pnpm. If you are still on an older version and the button reports an error, run the equivalent by hand (pnpm ≥ 11):
132
+
133
+ ```sh
134
+ cd "$HOME/.dsh/profiles/desktop" # Windows: cd "$env:USERPROFILE\.dsh\profiles\desktop"
135
+ pnpm add --save-exact dsh-grok-subscription@1.1.1
136
+ ```
137
+
138
+ 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.
139
+
131
140
  Uninstall with `dsh plugin --profile web remove dsh-grok-subscription`. This leaves the profile, other plugins, and the CLI's `auth.json` intact.
132
141
 
133
142
  The Settings logout action clears plugin-side session state; it does not revoke the official CLI session. If the CLI file remains, a later pull or startup may sync it again. To end the official session, use the official CLI / account's sign-out and authorization-management flow. Do not delete an entire DSH profile to handle one account.
@@ -18,7 +18,7 @@ dsh plugin --profile web list dsh-grok-subscription --depth 0
18
18
  需要可重复安装时,固定已发布版本,例如:
19
19
 
20
20
  ```sh
21
- dsh plugin --profile web add dsh-grok-subscription@1.1.0
21
+ dsh plugin --profile web add dsh-grok-subscription@1.1.1
22
22
  ```
23
23
 
24
24
  **GitHub 来源安装:**
@@ -128,6 +128,15 @@ dsh --profile headless "只回复:ok"
128
128
 
129
129
  npm 安装可在设置页更新,或运行 `dsh plugin --profile web add dsh-grok-subscription@latest`。GitHub 来源安装可运行 `dsh plugin --profile web update dsh-grok-subscription`。本地链接安装则拉取对应 checkout、测试并构建。更新后手动重启 DSH。
130
130
 
131
+ 桌面版的 `desktop` profile 由 Electron 应用独占,`dsh plugin --profile desktop …` 会被直接拒绝(`profile "desktop" is managed exclusively by the Electron application`),所以桌面版只能由插件自己更新。1.1.1 起「更新插件」会在该 profile 目录中用 DSH 自带的 pnpm 安装精确版本;若你仍停留在旧版本且按钮报错,可在终端手动执行(pnpm 需 ≥ 11):
132
+
133
+ ```sh
134
+ cd "$HOME/.dsh/profiles/desktop" # Windows: cd "$env:USERPROFILE\.dsh\profiles\desktop"
135
+ pnpm add --save-exact dsh-grok-subscription@1.1.1
136
+ ```
137
+
138
+ 然后完全退出并重启桌面版。更新成功后该 profile 的 `package.json` 里依赖应变为目标版本,`dsh.profile.bundles` 条目保持不变。仅刷新网页不够:Host 未重启时仍会加载旧版本。
139
+
131
140
  卸载使用 `dsh plugin --profile web remove dsh-grok-subscription`。这不删除整个 profile、其他插件或 Grok CLI 的 `auth.json`。
132
141
 
133
142
  设置页「登出」清理的是插件侧会话状态,不等于撤销官方 CLI 会话。CLI 文件仍然存在时,之后重新拉取或启动可能再次同步登录;彻底结束官方会话应使用官方 CLI / 账号提供的登出与授权管理流程。不要靠删除整个 DSH profile 来处理一个账号。
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 1.1.0",
42
+ subtitle: "\u7528 SuperGrok / X Premium\uFF08Grok Build\uFF09\u4F1A\u8BDD\uFF0C\u800C\u4E0D\u662F XAI_API_KEY\u3002\xB7 1.1.1",
43
43
  signedIn: "\u5DF2\u767B\u5F55",
44
44
  signedOut: "\u672A\u767B\u5F55",
45
45
  account: "\u8D26\u6237",
@@ -119,7 +119,7 @@ var zh = {
119
119
  var en = {
120
120
  nav: "Grok Subscription",
121
121
  title: "Grok Subscription",
122
- subtitle: "Use a SuperGrok / X Premium (Grok Build) session, not XAI_API_KEY. \xB7 1.1.0",
122
+ subtitle: "Use a SuperGrok / X Premium (Grok Build) session, not XAI_API_KEY. \xB7 1.1.1",
123
123
  signedIn: "Signed in",
124
124
  signedOut: "Signed out",
125
125
  account: "Account",
package/lib/index.js CHANGED
@@ -2121,6 +2121,7 @@ function createSessionService({
2121
2121
 
2122
2122
  // src/plugin-version.js
2123
2123
  import { spawn as spawn2 } from "node:child_process";
2124
+ import { existsSync as existsSync4 } from "node:fs";
2124
2125
  import { readdir, readFile, realpath } from "node:fs/promises";
2125
2126
  import { homedir as homedir3 } from "node:os";
2126
2127
  import { join as join4 } from "node:path";
@@ -2130,6 +2131,8 @@ var NPM_REGISTRY_LATEST_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest
2130
2131
  var DEFAULT_VERSION_TTL_MS = 5 * 6e4;
2131
2132
  var DEFAULT_VERSION_TIMEOUT_MS = 1e4;
2132
2133
  var DEFAULT_UPDATE_TIMEOUT_MS = 18e4;
2134
+ var DEFAULT_SETTLE_DELAY_MS = 250;
2135
+ var UPDATE_RELEASE_AGE_MINUTES = 0;
2133
2136
  var clone = (value) => structuredClone(value);
2134
2137
  function parseSemver(value) {
2135
2138
  if (typeof value !== "string") return void 0;
@@ -2163,6 +2166,16 @@ var readManifest = async (path) => {
2163
2166
  return void 0;
2164
2167
  }
2165
2168
  };
2169
+ async function confirmInstalled({ profileDir, expected, settleDelayMs, attempts = 3 }) {
2170
+ for (let attempt = 1; attempt <= attempts; attempt += 1) {
2171
+ const installed = (await readManifest(join4(profileDir, "node_modules", PACKAGE_NAME, "package.json")))?.version;
2172
+ if (installed === expected) return;
2173
+ if (attempt < attempts) await new Promise((resolve) => {
2174
+ setTimeout(resolve, settleDelayMs);
2175
+ });
2176
+ }
2177
+ throw new Error("Grok plugin update did not install the requested version");
2178
+ }
2166
2179
  async function findInstall({ dshHome, ownPackageJsonUrl }) {
2167
2180
  let ownReal;
2168
2181
  try {
@@ -2193,7 +2206,28 @@ async function findInstall({ dshHome, ownPackageJsonUrl }) {
2193
2206
  if (declared.length === 1) return { kind: classifySpec(declared[0].spec), profile: declared[0].profile };
2194
2207
  return { kind: "unknown" };
2195
2208
  }
2196
- function spawnRunCommand(argv, { signal, timeoutMs }) {
2209
+ var isExistingPath = (value) => typeof value === "string" && value !== "" && existsSync4(value);
2210
+ var PNPM_SCRIPT = /[\\/]pnpm\.(?:mjs|cjs|js)$/u;
2211
+ var dshRuntimeRoot = (value) => isExistingPath(value) && existsSync4(join4(value, "node_modules", "@deepseek-ai", "dsh", "package.json")) ? value : void 0;
2212
+ function resolvePnpm({ argv } = {}) {
2213
+ const entries = Array.isArray(argv) ? argv : [];
2214
+ for (const entry of entries) {
2215
+ if (isExistingPath(entry) && PNPM_SCRIPT.test(entry)) return entry;
2216
+ }
2217
+ for (const entry of entries) {
2218
+ const root = dshRuntimeRoot(entry);
2219
+ if (root === void 0) continue;
2220
+ const script = join4(root, "..", "pnpm", "bin", "pnpm.mjs");
2221
+ if (existsSync4(script)) return script;
2222
+ }
2223
+ return void 0;
2224
+ }
2225
+ function resolveLauncher({ argv, execPath }) {
2226
+ const pnpm = resolvePnpm({ argv });
2227
+ if (pnpm === void 0) return { command: "pnpm", prefix: [] };
2228
+ return { command: execPath, prefix: [pnpm] };
2229
+ }
2230
+ function spawnRunCommand({ command, args, cwd }, { signal, timeoutMs }) {
2197
2231
  return new Promise((resolve, reject) => {
2198
2232
  if (signal?.aborted) {
2199
2233
  reject(signal.reason instanceof Error ? signal.reason : new Error("Grok plugin update aborted"));
@@ -2213,7 +2247,11 @@ function spawnRunCommand(argv, { signal, timeoutMs }) {
2213
2247
  };
2214
2248
  let child;
2215
2249
  try {
2216
- child = spawn2(argv[0], argv.slice(1), { stdio: ["ignore", "pipe", "pipe"], signal: controller.signal });
2250
+ child = spawn2(command, args, {
2251
+ stdio: ["ignore", "pipe", "pipe"],
2252
+ signal: controller.signal,
2253
+ ...cwd === void 0 ? {} : { cwd }
2254
+ });
2217
2255
  } catch (error) {
2218
2256
  settle(reject, error);
2219
2257
  return;
@@ -2241,18 +2279,20 @@ function createGrokPluginManager({
2241
2279
  fetchImpl = globalThis.fetch,
2242
2280
  runCommand = spawnRunCommand,
2243
2281
  execPath = process.execPath,
2244
- binPath = process.argv[1],
2282
+ argv = process.argv,
2245
2283
  env = process.env,
2246
2284
  ownPackageJsonUrl = new URL("../package.json", import.meta.url),
2247
2285
  registryUrl = NPM_REGISTRY_LATEST_URL,
2248
2286
  now = Date.now,
2249
2287
  ttlMs = DEFAULT_VERSION_TTL_MS,
2250
2288
  timeoutMs = DEFAULT_VERSION_TIMEOUT_MS,
2251
- updateTimeoutMs = DEFAULT_UPDATE_TIMEOUT_MS
2289
+ updateTimeoutMs = DEFAULT_UPDATE_TIMEOUT_MS,
2290
+ settleDelayMs = DEFAULT_SETTLE_DELAY_MS
2252
2291
  } = {}) {
2253
2292
  if (typeof fetchImpl !== "function") throw new Error("Grok plugin manager requires fetch");
2254
2293
  if (typeof runCommand !== "function") throw new Error("Grok plugin manager requires runCommand");
2255
2294
  const dshHome = typeof env.DSH_HOME === "string" && env.DSH_HOME !== "" ? env.DSH_HOME : join4(homedir3(), ".dsh");
2295
+ const launcher = resolveLauncher({ argv, execPath });
2256
2296
  let cached;
2257
2297
  let inFlight;
2258
2298
  let generation = 0;
@@ -2341,15 +2381,30 @@ function createGrokPluginManager({
2341
2381
  throw new Error("Grok plugin update could not find the owning profile");
2342
2382
  }
2343
2383
  const latest = await fetchLatest(signal);
2344
- const argv = binPath === void 0 ? ["dsh", "plugin", "--profile", install.profile, "add", `${PACKAGE_NAME}@${latest}`] : [execPath, binPath, "plugin", "--profile", install.profile, "add", `${PACKAGE_NAME}@${latest}`];
2384
+ const profileDir = join4(dshHome, "profiles", install.profile);
2345
2385
  let result;
2346
2386
  try {
2347
- result = await runCommand(argv, { signal, timeoutMs: updateTimeoutMs });
2387
+ result = await runCommand({
2388
+ command: launcher.command,
2389
+ // `pnpm add <exact version>` is what `dsh plugin add` performs for a
2390
+ // registry spec. `--save-exact` keeps the profile dependency pinned,
2391
+ // and the release-age override stops a just-published version from
2392
+ // being skipped as too new (pnpm ≥ 10.16; unknown keys are ignored).
2393
+ args: [
2394
+ ...launcher.prefix,
2395
+ "add",
2396
+ "--save-exact",
2397
+ `--config.minimumReleaseAge=${UPDATE_RELEASE_AGE_MINUTES}`,
2398
+ `${PACKAGE_NAME}@${latest}`
2399
+ ],
2400
+ cwd: profileDir
2401
+ }, { signal, timeoutMs: updateTimeoutMs });
2348
2402
  } catch (error) {
2349
2403
  if (signal?.aborted) throw error;
2350
2404
  throw new Error("Grok plugin update failed");
2351
2405
  }
2352
2406
  if (result.code !== 0) throw new Error("Grok plugin update failed");
2407
+ await confirmInstalled({ profileDir, expected: latest, settleDelayMs });
2353
2408
  generation += 1;
2354
2409
  cached = void 0;
2355
2410
  return { version: latest, profile: install.profile };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-grok-subscription",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Use a SuperGrok or X Premium Grok Build subscription in DeepSeek Harness",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",