dsh-grok-subscription 1.0.18 → 1.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.en.md CHANGED
@@ -209,7 +209,7 @@ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web remove dsh-grok-subscrip
209
209
 
210
210
  - **`dsh` is not recognized**: the official npm route never creates a global `dsh` command — use the full `npx -y @deepseek-ai/dsh@0.1.5-rc.2 ...` command above;
211
211
  - **The model list is empty**: nothing is exposed while signed out. Finish signing in, then click **Pull from Grok CLI**;
212
- - **Sign-in opens no browser / chat fails with `fetch failed` / usage says "Billing request timed out"**: all three have one cause — `accounts.x.ai` and `cli-chat-proxy.grok.com` need a tunnel on some networks. Add `GROK_PROXY=http://127.0.0.1:10808` to `~/.dsh/.env`: it applies to **this plugin's Grok requests** (catalog, usage, chat) and to the **`grok` CLI** it spawns (sign-in, renewal), while DSH and every other provider stay direct — an `http_proxy` line there would route them all through the tunnel and break them whenever it is down. Restart the client afterwards; the sign-in link is handed to your browser and the panel also shows the one-time code and a clickable link. Standard proxy variables already present in the environment are inherited by the CLI too;
212
+ - **Sign-in opens no browser / chat fails with `fetch failed` / usage says "Billing request timed out"**: all three have one cause — `accounts.x.ai` and `cli-chat-proxy.grok.com` need a tunnel on some networks. This plugin does not configure a proxy of its own. When a tunnel is required, set the standard `https_proxy` / `http_proxy` in the launching environment or in `~/.dsh/.env` (never in a project `.env`). `@deepseek-ai/dsh-http-proxy` then routes `fetch` and the `grok` CLI this plugin spawns. Restart the client afterwards; the sign-in link is handed to your browser and the panel also shows the one-time code and a clickable link.
213
213
  - **Nothing changed after upgrading**: the plugin keeps running the old `lib/` — reinstall the plugin, restart `dsh web`, and hard-refresh (Ctrl+Shift+R);
214
214
  - **It reports `auth.json` permissions**: apply the `chmod 600` above; the plugin refuses symlinks and group- or other-readable files;
215
215
  - **"No reply" after sending a message**: upgrade to `1.0.1` or later. `1.0.0` had a defect where tool-calling turns aborted with a non-serializable stream chunk, leaving no reply in the UI at all.
package/README.md CHANGED
@@ -209,7 +209,7 @@ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web remove dsh-grok-subscrip
209
209
 
210
210
  - **`dsh` 无法识别**:官方 npm 方式本来就不会创建全局 `dsh` 命令,请使用上面的完整 `npx -y @deepseek-ai/dsh@0.1.5-rc.2 ...` 命令;
211
211
  - **模型列表是空的**:未登录时插件不暴露任何模型。先完成登录,再点 **从 Grok CLI 拉取**;
212
- - **登录不弹浏览器 / 聊天报 `fetch failed` / 用量「Billing request timed out」**:这三件事都指向同一个原因——`accounts.x.ai` 与 `cli-chat-proxy.grok.com` 在部分网络里必须走隧道。在 `~/.dsh/.env` 写一行 `GROK_PROXY=http://127.0.0.1:10808` 即可:它只作用于**本插件的 Grok 请求**(模型目录、用量、聊天)和它启动的 **`grok` CLI**(登录、续期),DSH 自身与其他 provider 仍走直连——把 `http_proxy` 写在这里会让所有 provider 一起走隧道,隧道一停就全连不上。写好后重启客户端;登录链接会交给系统浏览器打开,面板里同时显示一次性验证码与可点链接。环境里已有的标准代理变量同样会被 CLI 继承;
212
+ - **登录不弹浏览器 / 聊天报 `fetch failed` / 用量「Billing request timed out」**:这三件事都指向同一个原因——`accounts.x.ai` 与 `cli-chat-proxy.grok.com` 在部分网络里必须走隧道。插件不再自己配代理。需要隧道时,在启动环境或 `~/.dsh/.env` 里写标准变量 `https_proxy` / `http_proxy`(不要写进项目目录的 `.env`),宿主的 `@deepseek-ai/dsh-http-proxy` 会让 `fetch` 和本插件拉起的 `grok` CLI 一起走它。写好后重启客户端;登录链接会交给系统浏览器打开,面板里同时显示一次性验证码与可点链接。
213
213
  - **升级后界面没变化**:插件会继续运行旧的 `lib/`,请重新安装插件并重启 `dsh web`,然后硬刷新(Ctrl+Shift+R);
214
214
  - **提示 `auth.json` 权限不正确**:按上面的 `chmod 600` 处理;插件拒绝读取符号链接或组/其他用户可读的文件;
215
215
  - **出现「没有回复」**:请升级到 `1.0.1` 或更高版本。`1.0.0` 存在一个缺陷:工具调用轮次会因流片段无法无损序列化而整轮中止,界面上完全没有回复。
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.0.18",
42
+ subtitle: "\u7528 SuperGrok / X Premium\uFF08Grok Build\uFF09\u4F1A\u8BDD\uFF0C\u800C\u4E0D\u662F XAI_API_KEY\u3002\xB7 1.0.20",
43
43
  signedIn: "\u5DF2\u767B\u5F55",
44
44
  signedOut: "\u672A\u767B\u5F55",
45
45
  account: "\u8D26\u6237",
@@ -58,7 +58,7 @@ var zh = {
58
58
  deviceHint: "\u8BBE\u5907\u7801\u767B\u5F55\u4F1A\u8BA9 CLI \u6253\u5370\u4E00\u6B21\u6027\u9A8C\u8BC1\u7801\u548C\u94FE\u63A5\u3002\u82E5\u6D4F\u89C8\u5668\u6CA1\u6709\u81EA\u52A8\u6253\u5F00\uFF0C\u70B9\u63D0\u793A\u91CC\u7684\u201C\u6253\u5F00\u767B\u5F55\u9875\u9762\u201D\u5E76\u786E\u8BA4\u9A8C\u8BC1\u7801\u3002",
59
59
  loginWaiting: "\u7B49\u5F85\u6D4F\u89C8\u5668\u6388\u6743\u2026",
60
60
  loginOpenBrowser: "\u6253\u5F00\u767B\u5F55\u9875\u9762",
61
- loginNoUrl: "\u6CA1\u62FF\u5230\u767B\u5F55\u94FE\u63A5\uFF1A\u8BF7\u786E\u8BA4 grok CLI \u80FD\u8BBF\u95EE x.ai\uFF08\u684C\u9762\u7248\u901A\u5E38\u9700\u8981\u4EE3\u7406\uFF09\uFF0C\u7136\u540E\u91CD\u8BD5\u3002",
61
+ loginNoUrl: "\u6CA1\u62FF\u5230\u767B\u5F55\u94FE\u63A5\uFF1A\u8BF7\u786E\u8BA4 grok CLI \u80FD\u8BBF\u95EE x.ai\u3002\u684C\u9762\u7248\u9700\u8981\u4EE3\u7406\u65F6\uFF0C\u5728 ~/.dsh/.env \u8BBE\u7F6E https_proxy \u540E\u91CD\u542F\u3002",
62
62
  loginTimeout: "\u7B49\u5F85\u6388\u6743\u8D85\u65F6\uFF0C\u8BF7\u91CD\u65B0\u70B9\u51FB\u767B\u5F55\u3002",
63
63
  pullHint: "\u5B89\u5168\u8BFB\u53D6 ~/.grok/auth.json\uFF08\u62D2\u7EDD\u7B26\u53F7\u94FE\u63A5\u4E0E\u7EC4/\u5176\u4ED6\u4EBA\u53EF\u8BFB\uFF09\uFF0C\u53EA\u628A\u77ED\u671F access token \u5199\u5165 DSH\u3002",
64
64
  loginHelp: "\u767B\u5F55\u65B9\u5F0F\u8BF4\u660E",
@@ -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.0.18",
122
+ subtitle: "Use a SuperGrok / X Premium (Grok Build) session, not XAI_API_KEY. \xB7 1.0.20",
123
123
  signedIn: "Signed in",
124
124
  signedOut: "Signed out",
125
125
  account: "Account",
@@ -138,7 +138,7 @@ var en = {
138
138
  deviceHint: "Device-code login makes the CLI print a one-time code and link. If no browser opened, use \u201COpen the sign-in page\u201D in the status line and confirm the code.",
139
139
  loginWaiting: "Waiting for browser authorization\u2026",
140
140
  loginOpenBrowser: "Open the sign-in page",
141
- loginNoUrl: "No sign-in link was returned: make sure the grok CLI can reach x.ai (the desktop app usually needs a proxy), then retry.",
141
+ loginNoUrl: "No sign-in link was returned: make sure the grok CLI can reach x.ai. If the desktop app needs a proxy, set https_proxy in ~/.dsh/.env and restart.",
142
142
  loginTimeout: "Timed out waiting for authorization; click sign-in again.",
143
143
  pullHint: "Reads ~/.grok/auth.json securely (refuses symlinks and group/other-readable files) and stores only the short-lived access token in DSH.",
144
144
  loginHelp: "How signing in works",
package/lib/index.js CHANGED
@@ -42,9 +42,9 @@ var LOGIN_START_TIMEOUT_MS = 1e4;
42
42
  var LOGIN_HANDLER_TIMEOUT_MS = 2e4;
43
43
 
44
44
  // src/session.js
45
- import { existsSync as existsSync4 } from "node:fs";
45
+ import { existsSync as existsSync3 } from "node:fs";
46
46
  import { spawn } from "node:child_process";
47
- import { join as join4 } from "node:path";
47
+ import { join as join3 } from "node:path";
48
48
 
49
49
  // src/auth-file.js
50
50
  import { lstatSync, openSync, readFileSync, closeSync, constants as fsConstants } from "node:fs";
@@ -322,100 +322,6 @@ async function readResponseJson(response, options = {}) {
322
322
  return JSON.parse(await readResponseText(response, options));
323
323
  }
324
324
 
325
- // src/proxy.js
326
- import { existsSync as existsSync2 } from "node:fs";
327
- import { dirname, join as join2 } from "node:path";
328
- import { pathToFileURL } from "node:url";
329
- var GROK_API_HOSTS = Object.freeze(["cli-chat-proxy.grok.com"]);
330
- var HTTP_PROXY_PATTERN = /^https?:\/\//iu;
331
- var HOST_PROXY_PACKAGE = "@deepseek-ai/dsh-http-proxy";
332
- var installed;
333
- var dependencies = { undici: void 0, hostProxies: void 0 };
334
- function apiProxyUrl(env = process.env) {
335
- const named = [env?.GROK_API_PROXY, env?.GROK_PROXY];
336
- for (const candidate of named) {
337
- if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
338
- }
339
- return void 0;
340
- }
341
- function hostOf(origin) {
342
- try {
343
- return new URL(origin).hostname;
344
- } catch {
345
- return "";
346
- }
347
- }
348
- async function loadHostUndici() {
349
- let dir = dirname(process.argv[1] ?? "");
350
- for (let depth = 0; depth < 6 && dir && dir !== dirname(dir); depth++) {
351
- const entry = join2(dir, "node_modules", "undici", "index.js");
352
- if (existsSync2(entry)) {
353
- try {
354
- return await import(pathToFileURL(entry).href);
355
- } catch {
356
- break;
357
- }
358
- }
359
- dir = dirname(dir);
360
- }
361
- try {
362
- return await import("undici");
363
- } catch {
364
- return void 0;
365
- }
366
- }
367
- async function hostProxiesGrok() {
368
- if (typeof dependencies.hostProxies === "function") return dependencies.hostProxies();
369
- try {
370
- const mod = await import(HOST_PROXY_PACKAGE);
371
- const route = mod?.proxyRouteFor?.(`https://${GROK_API_HOSTS[0]}/`);
372
- return route?.proxied === true;
373
- } catch {
374
- return false;
375
- }
376
- }
377
- async function ensureApiRouting(env = process.env) {
378
- const url = apiProxyUrl(env);
379
- if (!url || !HTTP_PROXY_PATTERN.test(url)) return "direct";
380
- if (installed?.url === url) return "plugin";
381
- if (await hostProxiesGrok()) return "host";
382
- const undici = dependencies.undici ?? await loadHostUndici();
383
- const { Agent, Pool, ProxyAgent, getGlobalDispatcher, setGlobalDispatcher } = undici ?? {};
384
- if (typeof Agent !== "function" || typeof setGlobalDispatcher !== "function") return "direct";
385
- try {
386
- const tunnel = new ProxyAgent(url);
387
- const routing = new Agent({
388
- factory(origin, options) {
389
- return GROK_API_HOSTS.includes(hostOf(origin)) ? tunnel : new Pool(origin, options);
390
- }
391
- });
392
- const previous = typeof getGlobalDispatcher === "function" ? getGlobalDispatcher() : void 0;
393
- setGlobalDispatcher(routing);
394
- installed = {
395
- url,
396
- dispatcher: routing,
397
- restore: () => {
398
- if (previous !== void 0) setGlobalDispatcher(previous);
399
- installed = void 0;
400
- }
401
- };
402
- return "plugin";
403
- } catch {
404
- return "direct";
405
- }
406
- }
407
- function resetApiRouting() {
408
- const current = installed;
409
- installed = void 0;
410
- if (!current) return false;
411
- try {
412
- current.restore();
413
- return true;
414
- } catch {
415
- return false;
416
- }
417
- }
418
-
419
325
  // src/catalog.js
420
326
  var REASONING_LEVELS = Object.freeze(["low", "medium", "high", "xhigh"]);
421
327
  function asId(value) {
@@ -538,7 +444,6 @@ function toLlmModels(models) {
538
444
  });
539
445
  }
540
446
  async function fetchLiveCatalog(accessToken, options = {}) {
541
- await ensureApiRouting(options.env);
542
447
  const fetchImpl = options.fetch ?? globalThis.fetch;
543
448
  const signal = options.signal ?? AbortSignal.timeout(options.timeoutMs ?? CATALOG_TIMEOUT_MS);
544
449
  const response = await fetchImpl(MODELS_V2_URL, {
@@ -784,7 +689,6 @@ async function fetchBillingUsageOnce(accessToken, options = {}) {
784
689
  }
785
690
  let response;
786
691
  try {
787
- await ensureApiRouting(options.env);
788
692
  const signal = options.signal ?? AbortSignal.timeout(options.timeoutMs ?? USAGE_TIMEOUT_MS);
789
693
  response = await fetchImpl(BILLING_CREDITS_URL, {
790
694
  method: "GET",
@@ -862,11 +766,11 @@ async function fetchBillingUsage(accessToken, options = {}) {
862
766
  }
863
767
 
864
768
  // src/adapter.js
865
- import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
769
+ import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
866
770
  import { createRequire } from "node:module";
867
771
  import { homedir as homedir2 } from "node:os";
868
- import { dirname as dirname2, join as join3 } from "node:path";
869
- import { pathToFileURL as pathToFileURL2 } from "node:url";
772
+ import { dirname, join as join2 } from "node:path";
773
+ import { pathToFileURL } from "node:url";
870
774
  function withImportTimeout(promise, ms, message) {
871
775
  let timer;
872
776
  return Promise.race([
@@ -886,28 +790,28 @@ function hostModuleRoots(env = process.env, argv1 = process.argv[1]) {
886
790
  const override = env.DSH_GROK_PEER_ROOT;
887
791
  if (typeof override === "string" && override.trim()) push(override.trim());
888
792
  if (typeof argv1 === "string" && argv1) {
889
- let dir = dirname2(argv1);
890
- for (let depth = 0; depth < 6 && dir && dir !== dirname2(dir); depth++) {
891
- push(join3(dir, "node_modules"));
892
- dir = dirname2(dir);
793
+ let dir = dirname(argv1);
794
+ for (let depth = 0; depth < 6 && dir && dir !== dirname(dir); depth++) {
795
+ push(join2(dir, "node_modules"));
796
+ dir = dirname(dir);
893
797
  }
894
798
  }
895
799
  const prefix = env.NPM_CONFIG_PREFIX;
896
- if (typeof prefix === "string" && prefix.trim()) push(join3(prefix.trim(), "lib", "node_modules"));
800
+ if (typeof prefix === "string" && prefix.trim()) push(join2(prefix.trim(), "lib", "node_modules"));
897
801
  if (typeof process.execPath === "string" && process.execPath) {
898
- push(join3(dirname2(process.execPath), "..", "lib", "node_modules"));
802
+ push(join2(dirname(process.execPath), "..", "lib", "node_modules"));
899
803
  }
900
- push(join3("/opt/homebrew", "lib", "node_modules"));
901
- push(join3("/usr/local", "lib", "node_modules"));
804
+ push(join2("/opt/homebrew", "lib", "node_modules"));
805
+ push(join2("/usr/local", "lib", "node_modules"));
902
806
  for (const segment of ["Library/pnpm", ".local/share/pnpm", ".pnpm-global"]) {
903
- push(join3(homedir2(), segment, "node_modules"));
807
+ push(join2(homedir2(), segment, "node_modules"));
904
808
  }
905
809
  if (typeof env.DSH_PORTABLE_HOME === "string" && env.DSH_PORTABLE_HOME.trim()) {
906
- push(join3(env.DSH_PORTABLE_HOME.trim(), "node_modules"));
810
+ push(join2(env.DSH_PORTABLE_HOME.trim(), "node_modules"));
907
811
  }
908
- push(join3(homedir2(), ".local", "lib", "node_modules"));
909
- const dshHome = typeof env.DSH_HOME === "string" && env.DSH_HOME.trim() ? env.DSH_HOME.trim() : join3(homedir2(), ".dsh");
910
- push(join3(dshHome, "profiles", "node_modules"));
812
+ push(join2(homedir2(), ".local", "lib", "node_modules"));
813
+ const dshHome = typeof env.DSH_HOME === "string" && env.DSH_HOME.trim() ? env.DSH_HOME.trim() : join2(homedir2(), ".dsh");
814
+ push(join2(dshHome, "profiles", "node_modules"));
911
815
  return roots;
912
816
  }
913
817
  function splitSpecifier(specifier) {
@@ -951,14 +855,14 @@ function resolveExportsTarget(exportsField, subpath) {
951
855
  function resolveHostSpecifierManually(root, specifier) {
952
856
  const { name: name2, subpath } = splitSpecifier(specifier);
953
857
  const candidates = [
954
- join3(root, name2),
955
- join3(root, "node_modules", name2),
956
- join3(root, "@deepseek-ai", "dsh", "node_modules", name2),
957
- join3(root, "node_modules", "@deepseek-ai", "dsh", "node_modules", name2)
858
+ join2(root, name2),
859
+ join2(root, "node_modules", name2),
860
+ join2(root, "@deepseek-ai", "dsh", "node_modules", name2),
861
+ join2(root, "node_modules", "@deepseek-ai", "dsh", "node_modules", name2)
958
862
  ];
959
863
  for (const pkgDir of candidates) {
960
- const manifest = join3(pkgDir, "package.json");
961
- if (!existsSync3(manifest)) continue;
864
+ const manifest = join2(pkgDir, "package.json");
865
+ if (!existsSync2(manifest)) continue;
962
866
  let pkg;
963
867
  try {
964
868
  pkg = JSON.parse(readFileSync3(manifest, "utf8"));
@@ -967,15 +871,15 @@ function resolveHostSpecifierManually(root, specifier) {
967
871
  }
968
872
  const target = pkg.exports !== void 0 ? resolveExportsTarget(pkg.exports, subpath) : subpath === "." ? pkg.module ?? pkg.main ?? "index.js" : void 0;
969
873
  if (typeof target !== "string" || !target) continue;
970
- const file = join3(pkgDir, target);
971
- if (existsSync3(file)) return file;
874
+ const file = join2(pkgDir, target);
875
+ if (existsSync2(file)) return file;
972
876
  }
973
877
  return void 0;
974
878
  }
975
879
  function resolveHostSpecifier(specifier, roots = hostModuleRoots()) {
976
880
  for (const root of roots) {
977
881
  try {
978
- const resolved = createRequire(join3(root, "noop.js")).resolve(specifier);
882
+ const resolved = createRequire(join2(root, "noop.js")).resolve(specifier);
979
883
  if (typeof resolved === "string" && resolved) return resolved;
980
884
  } catch {
981
885
  }
@@ -991,7 +895,7 @@ async function optionalImport(specifier, options = {}) {
991
895
  const candidates = [specifier];
992
896
  if (!injected && !specifier.startsWith(".") && !specifier.startsWith("/") && !specifier.startsWith("file:")) {
993
897
  const resolved = resolveHostSpecifier(specifier, options.hostRoots ?? hostModuleRoots());
994
- if (resolved) candidates.push(pathToFileURL2(resolved).href);
898
+ if (resolved) candidates.push(pathToFileURL(resolved).href);
995
899
  }
996
900
  for (const candidate of candidates) {
997
901
  try {
@@ -1206,7 +1110,6 @@ function jsonSafeChunk(value) {
1206
1110
  return out;
1207
1111
  }
1208
1112
  async function* streamResponsesUnsafe(options, token) {
1209
- await ensureApiRouting();
1210
1113
  const headers = {
1211
1114
  Accept: "text/event-stream",
1212
1115
  "Content-Type": "application/json",
@@ -1642,7 +1545,6 @@ async function createGrokBuildAdapter(session, options = {}) {
1642
1545
  if (!responsesApi) {
1643
1546
  return { adapter: asHostAdapter(duck), kind: "custom-mvp", note: "openai-responses API module is unavailable; using the custom adapter." };
1644
1547
  }
1645
- await ensureApiRouting();
1646
1548
  responsesApi = withEncryptedReasoningInclude(responsesApi);
1647
1549
  const store = createStore(session);
1648
1550
  const authModels = piAi.createModels({
@@ -1734,43 +1636,17 @@ async function createGrokBuildAdapter(session, options = {}) {
1734
1636
  }
1735
1637
 
1736
1638
  // src/session.js
1737
- function resolveGrokBin(env = process.env, exists = existsSync4) {
1639
+ function resolveGrokBin(env = process.env, exists = existsSync3) {
1738
1640
  if (typeof env.DSH_GROK_BIN === "string" && env.DSH_GROK_BIN.trim()) return env.DSH_GROK_BIN.trim();
1739
- const local = join4(grokHome(env), "bin", "grok");
1641
+ const local = join3(grokHome(env), "bin", "grok");
1740
1642
  if (exists(local)) return local;
1741
1643
  return "grok";
1742
1644
  }
1743
- function grokCliAvailable(env = process.env, exists = existsSync4) {
1645
+ function grokCliAvailable(env = process.env, exists = existsSync3) {
1744
1646
  const bin = resolveGrokBin(env, exists);
1745
1647
  if (bin.includes("/") || bin.includes("\\")) return exists(bin);
1746
1648
  const delimiter = process.platform === "win32" ? ";" : ":";
1747
- return String(env.PATH ?? "").split(delimiter).some((dir) => dir && exists(join4(dir, bin)));
1748
- }
1749
- var STANDARD_PROXY_NAMES = [
1750
- "http_proxy",
1751
- "https_proxy",
1752
- "all_proxy",
1753
- "no_proxy",
1754
- "HTTP_PROXY",
1755
- "HTTPS_PROXY",
1756
- "ALL_PROXY",
1757
- "NO_PROXY"
1758
- ];
1759
- function cliProxyEnv(env = process.env) {
1760
- const base = env ?? process.env;
1761
- const declared = STANDARD_PROXY_NAMES.some((name2) => typeof base[name2] === "string" && base[name2].trim() !== "");
1762
- if (declared) return base;
1763
- const named = [base.GROK_CLI_PROXY, base.GROK_PROXY].find((value) => typeof value === "string" && value.trim() !== "");
1764
- const proxy = typeof named === "string" ? named.trim() : "";
1765
- if (!proxy) return base;
1766
- const bypass = typeof base.GROK_CLI_NO_PROXY === "string" && base.GROK_CLI_NO_PROXY.trim() ? base.GROK_CLI_NO_PROXY.trim() : "localhost,127.0.0.1,::1";
1767
- const httpish = /^https?:\/\//iu.test(proxy);
1768
- return {
1769
- ...base,
1770
- ...httpish ? { http_proxy: proxy, https_proxy: proxy } : {},
1771
- all_proxy: proxy,
1772
- no_proxy: bypass
1773
- };
1649
+ return String(env.PATH ?? "").split(delimiter).some((dir) => dir && exists(join3(dir, bin)));
1774
1650
  }
1775
1651
  function openExternal(url, options = {}) {
1776
1652
  const spawnFn = options.spawn ?? spawn;
@@ -1797,7 +1673,7 @@ function openExternal(url, options = {}) {
1797
1673
  }
1798
1674
  var LOGIN_URL_PATTERN = /https?:\/\/[^\s<>"'`\\]+/u;
1799
1675
  var DEVICE_CODE_PATTERN = /\b([A-Z0-9]{4}-[A-Z0-9]{4})\b/u;
1800
- function spawnGrokLogin(options = {}) {
1676
+ async function spawnGrokLogin(options = {}) {
1801
1677
  const spawnFn = options.spawn ?? spawn;
1802
1678
  const bin = resolveGrokBin(options.env, options.exists);
1803
1679
  const args = options.device ? ["login", "--device-auth"] : ["login"];
@@ -1808,7 +1684,7 @@ function spawnGrokLogin(options = {}) {
1808
1684
  try {
1809
1685
  child = spawnFn(bin, args, {
1810
1686
  stdio: options.stdio ?? ["ignore", "pipe", "pipe"],
1811
- env: cliProxyEnv(options.env)
1687
+ env: options.env ?? process.env
1812
1688
  });
1813
1689
  } catch (error) {
1814
1690
  reject(new Error(`Could not start grok CLI (${bin})`, { cause: error }));
@@ -1871,7 +1747,7 @@ function spawnGrokLogin(options = {}) {
1871
1747
  });
1872
1748
  });
1873
1749
  }
1874
- function spawnGrokRefresh(options = {}) {
1750
+ async function spawnGrokRefresh(options = {}) {
1875
1751
  const spawnFn = options.spawn ?? spawn;
1876
1752
  const bin = resolveGrokBin(options.env, options.exists);
1877
1753
  const timeoutMs = typeof options.timeoutMs === "number" && options.timeoutMs > 0 ? options.timeoutMs : CLI_REFRESH_TIMEOUT_MS;
@@ -1880,7 +1756,7 @@ function spawnGrokRefresh(options = {}) {
1880
1756
  try {
1881
1757
  child = spawnFn(bin, ["models"], {
1882
1758
  stdio: options.stdio ?? "ignore",
1883
- env: cliProxyEnv(options.env)
1759
+ env: options.env ?? process.env
1884
1760
  });
1885
1761
  } catch (error) {
1886
1762
  reject(new Error(`Could not start grok CLI (${bin})`, { cause: error }));
@@ -2247,7 +2123,7 @@ function createSessionService({
2247
2123
  import { spawn as spawn2 } from "node:child_process";
2248
2124
  import { readdir, readFile, realpath } from "node:fs/promises";
2249
2125
  import { homedir as homedir3 } from "node:os";
2250
- import { join as join5 } from "node:path";
2126
+ import { join as join4 } from "node:path";
2251
2127
  import { fileURLToPath } from "node:url";
2252
2128
  var PACKAGE_NAME = PLUGIN_ID;
2253
2129
  var NPM_REGISTRY_LATEST_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
@@ -2296,21 +2172,21 @@ async function findInstall({ dshHome, ownPackageJsonUrl }) {
2296
2172
  }
2297
2173
  let entries = [];
2298
2174
  try {
2299
- entries = await readdir(join5(dshHome, "profiles"), { withFileTypes: true });
2175
+ entries = await readdir(join4(dshHome, "profiles"), { withFileTypes: true });
2300
2176
  } catch {
2301
2177
  entries = [];
2302
2178
  }
2303
2179
  const declared = [];
2304
2180
  for (const entry of entries) {
2305
2181
  if (!entry.isDirectory()) continue;
2306
- const profileDir = join5(dshHome, "profiles", entry.name);
2307
- const spec = (await readManifest(join5(profileDir, "package.json")))?.dependencies?.[PACKAGE_NAME];
2182
+ const profileDir = join4(dshHome, "profiles", entry.name);
2183
+ const spec = (await readManifest(join4(profileDir, "package.json")))?.dependencies?.[PACKAGE_NAME];
2308
2184
  if (typeof spec !== "string") continue;
2309
2185
  declared.push({ profile: entry.name, spec });
2310
2186
  if (ownReal === void 0) continue;
2311
2187
  try {
2312
- const installed2 = await realpath(join5(profileDir, "node_modules", PACKAGE_NAME, "package.json"));
2313
- if (installed2 === ownReal) return { kind: classifySpec(spec), profile: entry.name };
2188
+ const installed = await realpath(join4(profileDir, "node_modules", PACKAGE_NAME, "package.json"));
2189
+ if (installed === ownReal) return { kind: classifySpec(spec), profile: entry.name };
2314
2190
  } catch {
2315
2191
  }
2316
2192
  }
@@ -2376,7 +2252,7 @@ function createGrokPluginManager({
2376
2252
  } = {}) {
2377
2253
  if (typeof fetchImpl !== "function") throw new Error("Grok plugin manager requires fetch");
2378
2254
  if (typeof runCommand !== "function") throw new Error("Grok plugin manager requires runCommand");
2379
- const dshHome = typeof env.DSH_HOME === "string" && env.DSH_HOME !== "" ? env.DSH_HOME : join5(homedir3(), ".dsh");
2255
+ const dshHome = typeof env.DSH_HOME === "string" && env.DSH_HOME !== "" ? env.DSH_HOME : join4(homedir3(), ".dsh");
2380
2256
  let cached;
2381
2257
  let inFlight;
2382
2258
  let generation = 0;
@@ -2760,18 +2636,6 @@ function apply(ctx, options = {}) {
2760
2636
  "grok-subscription: startup lifetime"
2761
2637
  );
2762
2638
  }
2763
- void ensureApiRouting().then((mode) => {
2764
- if (mode === "direct") return;
2765
- ctx.logger?.debug?.("Grok subscription API route: %s", mode);
2766
- }).catch((error) => {
2767
- ctx.logger?.debug?.(
2768
- "Grok subscription API route skipped: %s",
2769
- error instanceof Error ? error.message : "unknown"
2770
- );
2771
- });
2772
- if (typeof ctx.effect === "function") {
2773
- ctx.effect(() => () => resetApiRouting(), "grok-subscription: API proxy route");
2774
- }
2775
2639
  const notifyCatalogChange = () => {
2776
2640
  scheduleDeferred2(() => {
2777
2641
  if (!active) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-grok-subscription",
3
- "version": "1.0.18",
3
+ "version": "1.0.20",
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",