dsh-grok-subscription 1.0.20 → 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 ADDED
@@ -0,0 +1,20 @@
1
+ # Changelog
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
+
11
+ ## 1.1.0 — 2026-09-28
12
+
13
+ - Add the original Comet Navigator mascot and align the Chinese/English homepages around features, installation, daily use, screenshots, and maintenance.
14
+ - Add bilingual usage guides covering the official CLI requirement, subscription sessions, model access, image input, experimental quota, troubleshooting, and safe removal.
15
+ - Ship the usage guides alongside the existing screenshots and mascot in npm and release archives.
16
+ - Align the manifest, lockfile root, Settings subtitle, and pinned install examples on 1.1.0; add release metadata and documentation packaging regression checks.
17
+ - Clarify the image-input model ID as `grok-4.7-build-fast`. This is a documentation correction, not a new image-processing capability.
18
+ - No model-routing, authentication, proxy, quota, or dependency behavior changes. This release carries forward the runtime fixes in 1.0.20.
19
+
20
+ Earlier changes are recorded in the [repository history](https://github.com/BaronCyrus/dsh-grok-subscription/commits/main) and [GitHub Releases](https://github.com/BaronCyrus/dsh-grok-subscription/releases).
package/README.en.md CHANGED
@@ -1,234 +1,175 @@
1
1
  <div align="center">
2
2
 
3
- # DSH Grok Subscription — Use SuperGrok / X Premium subscriptions in DeepSeek Harness
3
+ <img src="docs/assets/dsh-grok-mascot.png" width="220" height="220" alt="DSH Grok Subscription mascot: Comet Navigator">
4
4
 
5
- [简体中文](https://github.com/BaronCyrus/dsh-grok-subscription/blob/main/README.md) · **English**
5
+ # DSH Grok Subscription
6
6
 
7
- **Use your SuperGrok / X Premium (Grok Build) subscription directly in DeepSeek Harness**
7
+ [简体中文](README.md) · **English**
8
8
 
9
- Reuse the official Grok Build CLI session — no `XAI_API_KEY` needed.
10
- Models, reasoning effort, and weekly quota all stay inside DSH.
9
+ **Code, ask about images, and adjust reasoning in DSH with your Grok Build subscription.**
10
+
11
+ Reuse the official Grok Build CLI session to select models, attach images, and check weekly quota inside DeepSeek Harness.
12
+ No separate pay-as-you-go xAI API key is required.
11
13
 
12
14
  [![CI](https://github.com/BaronCyrus/dsh-grok-subscription/actions/workflows/ci.yml/badge.svg)](https://github.com/BaronCyrus/dsh-grok-subscription/actions/workflows/ci.yml)
13
15
  [![npm](https://img.shields.io/npm/v/dsh-grok-subscription?logo=npm&label=npm)](https://www.npmjs.com/package/dsh-grok-subscription)
14
- [![total npm downloads](https://img.shields.io/npm/dt/dsh-grok-subscription?logo=npm&label=total%20downloads)](https://www.npmjs.com/package/dsh-grok-subscription)
16
+ [![Total npm downloads](https://img.shields.io/npm/dt/dsh-grok-subscription?logo=npm&label=total%20downloads)](https://www.npmjs.com/package/dsh-grok-subscription)
15
17
  [![MIT](https://img.shields.io/badge/license-MIT-111111.svg)](LICENSE)
16
18
  [![Star](https://img.shields.io/github/stars/BaronCyrus/dsh-grok-subscription?style=flat&logo=github&label=Star)](https://github.com/BaronCyrus/dsh-grok-subscription/stargazers)
17
19
 
18
- [Three-step start](#three-step-start) · [Install](#install) · [Contribute](CONTRIBUTING.md) · [Update and uninstall](#update-and-uninstall)
20
+ [Features](#features) · [Install](#install) · [Daily use](#daily-use) · [Screenshots](#screenshots) · [User guide](#user-guide) · [Update and uninstall](#update-and-uninstall)
19
21
 
20
22
  </div>
21
23
 
22
- <p align="center">
23
- <img src="docs/assets/grok-subscription-overview.webp" width="900" alt="Select Grok 4.7 in DeepSeek Harness and chat through a SuperGrok subscription">
24
- </p>
25
-
26
- ## Three-step start
27
-
28
- 1. **Install the plugin.** Run the command below; to select a candidate version, enter the full `package@version`, for example `dsh-grok-subscription@1.0.10`.
29
-
30
- ```sh
31
- dsh plugin --profile web add BaronCyrus/dsh-grok-subscription
32
- ```
33
-
34
- 2. **Sign in to the subscription.** Open **Settings → Grok Subscription** and click **CLI login** or **Device-code login**. The plugin runs the official `grok login`, hands the link the CLI prints to your browser, and shows the one-time code plus a clickable link in the panel; the session syncs itself once you authorize. If you already ran `grok login` yourself, just click **Pull from Grok CLI** — nothing has to be pasted.
35
- 3. **Start using it.** Pick a model such as Grok 4.7 in the model picker. The round badge next to the picker shows weekly remaining quota, and the model menu offers reasoning effort levels.
24
+ <a id="why-this-plugin"></a>
36
25
 
37
- Restart `dsh web` after installing or upgrading, otherwise the old `lib/` keeps running.
38
-
39
- ## Why this plugin
26
+ ## Features
40
27
 
41
- | Capability | What you get |
28
+ | Capability | What it does |
42
29
  | --- | --- |
43
- | **Direct subscription routing** | Reuse the official Grok Build CLI session — no `XAI_API_KEY` needed |
44
- | **Real model catalog** | Read the models the account can actually use (such as `grok-4.7`, `grok-4.6`, `grok-4.5`) from `/v1/models-v2`; nothing is exposed while signed out |
45
- | **Reasoning effort** | The model picker offers `low` / `medium` / `high` / `xhigh`, defaulting to `high`, matching the Codex interaction |
46
- | **Image input** | `grok-4.7` / `grok-4.7-fast` / `grok-4.6` accept pasted images, normalized to the host's pixel and byte budget by its attachment service |
47
- | **Composer quota** | A badge beside the model picker shows weekly remaining percentage; hover or click for "Weekly quota · N% left · resets M/D HH:mm" |
48
- | **Usage panel (experimental)** | Settings shows the used and remaining percentages the backend reports, and never invents numbers when the read fails |
49
- | **Credentials stay local** | Only the short-lived access token from `~/.grok/auth.json` is read on the host; no token is handed to browser RPC |
50
- | **Sign-in state refreshes the UI** | Login, pull, and logout emit `llm/adapters-updated`, so the chat model list updates with them |
51
- | **Automatic token renewal** | The access token only lives 6 hours; near expiry, or on a 401, the plugin runs the official `grok` CLI to refresh `auth.json` and retries once, so you never re-login by hand |
52
- | **Failures stay visible** | When subscription routing is unavailable it reports an error instead of silently using another paid route |
53
-
54
- These capabilities reuse the same local Grok Build sign-in.
55
-
56
- ## Product screen
57
-
58
- <p align="center">
59
- <img src="docs/assets/settings-account.webp" width="820" alt="The Grok Subscription page in DSH Settings: sign-in status, account, login buttons and credential notes">
60
- </p>
30
+ | **Reuse subscription sign-in** | Start CLI / device-code login in Settings, or pull an existing Grok CLI session without manually pasting tokens |
31
+ | **Model catalog sync** | Prefers the account's live catalog after sign-in, with a built-in fallback when that read fails; no models appear while signed out |
32
+ | **Reasoning effort** | Select the levels offered by each model, typically `low` / `medium` / `high` / `xhigh`, with `high` preferred by default |
33
+ | **Image input** | Paste or attach images for supported models; Settings shows the active adapter path and attachment capability |
34
+ | **Weekly quota** | The composer badge and Settings show reported usage; the experimental quota reader never invents missing numbers |
35
+ | **Session renewal and updates** | Attempts renewal through the official CLI near token expiry or after an authentication rejection; Settings also checks plugin versions |
36
+ | **No tokens in browser responses** | Access tokens are used Host-side; a subscription failure never silently selects another paid model route |
61
37
 
62
- The **Settings → Grok Subscription** screen uses a status chip for the sign-in state, and an account card offering CLI login, device-code login, pull from the Grok CLI, and logout; how credentials are read lives in a collapsible "How signing in works" disclosure. It is styled with DSH's own design tokens, so it follows the light and dark theme. Account and time values in the screenshot are demo data.
38
+ <a id="three-step-start"></a>
39
+ <a id="prepare-dsh"></a>
63
40
 
64
- <p align="center">
65
- <img src="docs/assets/settings-usage.webp" width="820" alt="The experimental usage panel in Grok Subscription settings: 6% used, about 94% remaining">
66
- </p>
67
-
68
- The experimental usage panel comes from an undocumented subscription billing endpoint (`/v1/billing?format=credits`): the remaining share is drawn as a progress bar and per-product rows are listed separately. It is informational: the endpoint may change or disappear, a failed read never shows an invented percentage, and chat is unaffected.
69
-
70
- ## Prepare DSH
71
-
72
- This plugin supports the latest DeepSeek Harness release recorded in its package metadata and requires a **SuperGrok or X Premium** account that currently has Grok Build access.
73
-
74
- - **Already able to run `dsh`**: use the standard command below;
75
- - **Prefer the official path**: see the [DeepSeek Harness documentation](https://github.com/deepseek-ai/deepseek-harness#run).
76
-
77
- The plugin is strict about `~/.grok/auth.json`: it refuses symbolic links, files readable by group or others, and files not owned by the current user. If permissions are wrong:
41
+ ## Install
78
42
 
79
- ```sh
80
- chmod 600 "${GROK_HOME:-$HOME/.grok}/auth.json"
81
- ```
43
+ You need **DeepSeek Harness**, the **official Grok Build CLI on the same machine**, and a SuperGrok / X Premium account that **currently has Grok Build access**. The subscription name alone does not guarantee that access; the account's actual authorization determines it.
82
44
 
83
- ## Install
45
+ For DSH setup, see the [official instructions](https://github.com/deepseek-ai/deepseek-harness#run). Version requirements and CLI paths are covered in [Installation and compatibility](docs/guide.en.md#installation-and-compatibility).
84
46
 
85
- ### Standard DSH command
47
+ ### 1. Install the plugin
86
48
 
87
49
  ```sh
88
- dsh plugin --profile web add BaronCyrus/dsh-grok-subscription
50
+ dsh plugin --profile web add dsh-grok-subscription@latest
89
51
  ```
90
52
 
91
- You can also install the version published on npm:
53
+ Then **manually restart the target DSH instance**. Refreshing the browser alone does not reload the Host adapter.
92
54
 
93
- ```sh
94
- dsh plugin --profile web add dsh-grok-subscription@1.0.10
95
- ```
55
+ ### 2. Sign in
96
56
 
97
- DSH handles target selection, the profile lock, dependency resolution, and bundle activation.
57
+ Open **Settings → Grok Subscription** and select **CLI login** or **Device-code login**. Follow the browser and panel instructions. If you already ran `grok login`, select **Pull from Grok CLI**.
98
58
 
99
- ### Headless
59
+ > This plugin relies on the official Grok Build CLI for sign-in and renewal; it is not CLI-independent. Do not paste `XAI_API_KEY`, and never share `auth.json` or tokens in chats, screenshots, or public issues.
100
60
 
101
- Sign in and select a Grok model once in the Web UI, then install the same plugin into the standard DSH Headless profile:
61
+ ### 3. Select a model
102
62
 
103
- ```sh
104
- dsh plugin --profile headless add BaronCyrus/dsh-grok-subscription
105
- dsh --profile headless "reply with exactly: ok"
106
- ```
63
+ Pick a Grok model your account can use, adjust reasoning effort as needed, and start chatting or coding. The badge beside the model shows weekly quota when usage can be read successfully.
107
64
 
108
65
  <details>
109
- <summary>Official npm route (Node.js installed)</summary>
110
-
111
- The official `npx @deepseek-ai/dsh web` does not create a global `dsh` command, so keep the full `npx` prefix when installing the plugin:
66
+ <summary>Verify the install / use npx / pin a version</summary>
112
67
 
113
68
  ```sh
114
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web add BaronCyrus/dsh-grok-subscription
115
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web list dsh-grok-subscription --depth 0
116
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 --profile web --dump-config
69
+ dsh plugin --profile web list dsh-grok-subscription --depth 0
117
70
  ```
118
71
 
119
- </details>
120
-
121
- <details>
122
- <summary>Verify the install when <code>dsh</code> already works</summary>
72
+ Without a global `dsh` command, retain your full `npx` launcher prefix. This example uses the baseline version declared in the package metadata:
123
73
 
124
74
  ```sh
125
- dsh plugin --profile web list dsh-grok-subscription --depth 0
126
- dsh --profile web --dump-config
75
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web add dsh-grok-subscription@latest
127
76
  ```
128
77
 
129
- The package list should contain exactly one `dsh-grok-subscription`, and the config exactly one `grok-build` route.
78
+ See the [full user guide](docs/guide.en.md) for pinned npm versions, GitHub-source installs, CLI paths, and Headless usage.
130
79
 
131
80
  </details>
132
81
 
133
- Restart DSH manually afterwards, then:
82
+ ## Daily use
134
83
 
135
- 1. Open **Settings → Grok Subscription**;
136
- 2. Sign in with an account that has Grok Build access (browser login or device-code login);
137
- 3. Select a Grok model in the model picker.
84
+ **Choose a model and effort.** The catalog refreshes after sign-in. Use the effort levels shown for the selected model. A built-in fallback catalog does not grant additional model access.
138
85
 
139
- ## Features
86
+ **Ask about images.** Paste or attach an image while using a supported model. The current implementation advertises image input for `grok-4.7`, `grok-4.7-build-fast`, and `grok-4.6`, but not `grok-4.5`. This means **reading images, not generating them**. See [Image input](docs/guide.en.md#image-input).
140
87
 
141
- - Reuses the official Grok Build CLI session; credentials stay local and the account is identified by a partially masked email;
142
- - Models appear directly in DSH sessions with no `XAI_API_KEY`, and no token is exposed to the browser;
143
- - The model catalog is pulled after sign-in; a failed or timed-out read falls back to a built-in list and records the error, and it stays empty while signed out;
144
- - The model menu offers `low` / `medium` / `high` / `xhigh` reasoning effort, defaulting to `high`;
145
- - A weekly remaining quota badge sits beside the model picker in the composer, with remaining percentage and reset time on hover or click;
146
- - Settings can show the used and remaining percentages the backend reports, and says so plainly instead of guessing when the read fails;
147
- - Supports CLI login, device-code login, pull from the Grok CLI, and logout;
148
- - Renews the access token automatically: near the end of its 6-hour life, or on a 401, it runs the official `grok` CLI and retries once, so a session never lapses mid-use; the chat model list refreshes whenever sign-in state changes;
149
- - When subscription routing is unavailable it reports an error instead of silently switching to another paid route;
150
- - Prefix caching follows xAI's automatic prompt-cache semantics: one DSH session keeps a stable `prompt_cache_key`, tool definitions stay in a stable order, and the fallback adapter preserves and replays `reasoning.encrypted_content` unchanged. Server-side eviction can still miss, and the plugin never invents a hit rate.
88
+ **Check weekly quota.** With the `grok-build` route selected, the badge shows the remaining percentage when the read succeeds; hover or click for the reset time. Settings has the full details. A failed quota read does not itself block chat.
151
89
 
152
- ### Composer quota
90
+ <a id="product-screen"></a>
91
+
92
+ ## Screenshots
153
93
 
154
94
  <p align="center">
155
- <img src="docs/assets/composer-quota.webp" width="820" alt="DSH composer: weekly remaining quota badge beside the Grok 4.7 model picker">
95
+ <img src="docs/assets/grok-subscription-overview.webp" width="900" alt="Select a Grok subscription model and chat in DSH">
156
96
  </p>
157
97
 
158
- The badge appears only when the current session's provider is `grok-build` and the usage read succeeds; hover or click for "Weekly quota · N% left · resets M/D HH:mm". It reflects only the weekly quota the backend returns, and when the read fails the badge is simply hidden — chat is unaffected.
159
-
160
- ### Image input
98
+ <p align="center">
99
+ <img src="docs/assets/composer-quota.webp" width="820" alt="Weekly remaining-quota badge beside the Grok model picker">
100
+ </p>
161
101
 
162
- `grok-4.7`, `grok-4.7-fast` and `grok-4.6` accept image input: paste or attach an image in the composer and ask about it. Images are normalized to the host's pixel and byte budget by its attachment service before they are sent, and an over-budget image degrades to a text description rather than being dropped silently.
102
+ <details>
103
+ <summary>Show the sign-in and experimental usage panels</summary>
163
104
 
164
- **Both paths support it**: when the host's official `pi-ai` adapter is available it handles images, and otherwise the bundled fallback adapter reads the attachment bytes itself and inlines them as `input_image`. Image support therefore does not depend on resolving the host's packages. The **Active path** row in Settings shows which one is live and whether image input is available — check it first when a model rejects an image.
105
+ <p align="center">
106
+ <img src="docs/assets/settings-account.webp" width="820" alt="Account status and sign-in actions in Grok Subscription settings">
107
+ </p>
165
108
 
166
- > If it says "bundled fallback" and images are rejected, `dsh web` most likely was not restarted after updating: the client UI refreshes from disk, but the host adapter is loaded at process start.
109
+ <p align="center">
110
+ <img src="docs/assets/settings-usage.webp" width="820" alt="Experimental usage panel in Grok Subscription settings">
111
+ </p>
167
112
 
168
- `grok-4.5` is **deliberately excluded**. Given a solid red image and asked its colour it answered "green", and it described a yellow square as a "circle with a black outline" — it confabulates instead of looking. The plugin therefore does not advertise image input for it, so it cannot return confident nonsense.
113
+ Identity and time values in the account screenshot are demo data. Usage screenshots illustrate the UI, not a fixed allowance for any account.
169
114
 
170
- ### Reasoning effort
115
+ </details>
171
116
 
172
- After selecting a Grok model, the model menu exposes a reasoning effort submenu: `low` / `medium` / `high` / `xhigh`, defaulting to `high`. The levels come from `model.reasoning` metadata (`efforts` + `defaultEffort`), so the interaction matches Codex in DSH; the levels actually available depend on the account's model catalog.
117
+ ## User guide
173
118
 
174
- ### Model catalog and sign-in state
119
+ The [full user guide](docs/guide.en.md) covers CLI sign-in, the model catalog, images, quota limitations, network troubleshooting, Headless usage, and development.
175
120
 
176
- After sign-in the plugin reads the model catalog the account can actually use from the subscription proxy; while signed out it registers no models at all. If the read fails or times out it falls back to a built-in list (`grok-4.7` / `grok-4.6` / `grok-4.5`) and records the error in status, so the catalog is never left empty and plugin startup is never blocked.
121
+ Quick links: [Sign-in and credentials](docs/guide.en.md#sign-in-and-credentials) · [Image input](docs/guide.en.md#image-input) · [Troubleshooting](docs/guide.en.md#troubleshooting) · [Contributing](CONTRIBUTING.md).
177
122
 
178
123
  ## Update and uninstall
179
124
 
180
- ### Update and verify
125
+ **Update an npm installation:** check versions in Settings. Supported npm installs can update there, or you can run:
181
126
 
182
127
  ```sh
183
- dsh plugin --profile web update dsh-grok-subscription
184
- dsh plugin --profile web list dsh-grok-subscription --depth 0
185
- dsh --profile web --dump-config
128
+ dsh plugin --profile web add dsh-grok-subscription@latest
186
129
  ```
187
130
 
188
- ### Uninstall
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
+
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).
189
134
 
190
- Confirm you want the plugin removed, then run:
135
+ **Uninstall:**
191
136
 
192
137
  ```sh
193
138
  dsh plugin --profile web remove dsh-grok-subscription
194
139
  ```
195
140
 
196
- These operations keep the DSH profile, other plugins, and the sign-in stored in `~/.grok/auth.json`.
141
+ Restart DSH afterwards. Removal does not delete other plugins, the whole profile, or the CLI's `auth.json`; it is not the same as signing out of the official CLI. See [Updates and sign-out](docs/guide.en.md#updates-and-sign-out).
197
142
 
198
- <details>
199
- <summary>Official npm fallback</summary>
143
+ <a id="troubleshooting"></a>
200
144
 
201
- ```sh
202
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web update dsh-grok-subscription
203
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web remove dsh-grok-subscription
204
- ```
145
+ ## FAQ
205
146
 
206
- </details>
147
+ **Empty model list?** Confirm that the official CLI has a subscription session, then select **Pull from Grok CLI** in Settings. An API-key-only CLI configuration is not a subscription login.
207
148
 
208
- ## Troubleshooting
149
+ **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).
209
150
 
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
- - **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. 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
- - **Nothing changed after upgrading**: the plugin keeps running the old `lib/` — reinstall the plugin, restart `dsh web`, and hard-refresh (Ctrl+Shift+R);
214
- - **It reports `auth.json` permissions**: apply the `chmod 600` above; the plugin refuses symlinks and group- or other-readable files;
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.
216
- - **Chat or usage reports 401 "Invalid or expired credentials"**: a Grok access token only lives about 6 hours, and once it lapses chat and usage fail together. From `1.0.5` the plugin renews it through the official CLI automatically; on older versions run any `grok` command (for example `grok models`) to refresh `~/.grok/auth.json`, then click **Pull from Grok CLI**.
151
+ **Images still unavailable after updating?** Fully restart DSH, check the model's image support, and check the attachment capability shown under **Active path** in Settings.
217
152
 
218
153
  ## Scope and support
219
154
 
220
- The Grok subscription backend and DSH can change independently; this is a community project with no affiliation or endorsement from DeepSeek or xAI.
155
+ This is a community plugin, not affiliated with or endorsed by DeepSeek or xAI. Model access, reasoning options, and quota depend on the account and backend; the plugin does not grant extra entitlements.
156
+
157
+ The usage panel depends on an undocumented billing endpoint and is **experimental**. Upstream changes may make it unavailable. Keeping credentials out of browser responses does not mean offline inference: model requests still go to the Grok subscription service.
221
158
 
222
- For sensitive issues read [SECURITY.md](SECURITY.md) first. For bug reports use [Issues](https://github.com/BaronCyrus/dsh-grok-subscription/issues).
159
+ See [SECURITY.md](SECURITY.md) and use [Issues](https://github.com/BaronCyrus/dsh-grok-subscription/issues) for reports. Never publish login files, tokens, raw account responses, or complete login callbacks.
223
160
 
224
- ### Development checks
161
+ ## Local development
225
162
 
226
163
  ```sh
227
- npm install
164
+ git clone https://github.com/BaronCyrus/dsh-grok-subscription.git
165
+ cd dsh-grok-subscription
166
+ npm ci
228
167
  npm test
229
168
  npm run build
230
169
  ```
231
170
 
232
- `lib/` is a committed build artifact, so run `npm run build` after changing `src/`.
171
+ `lib/` contains committed build output. Rebuild it after changing `src/` rather than editing it by hand. See [CONTRIBUTING.md](CONTRIBUTING.md) for development and verification requirements.
172
+
173
+ ## License
233
174
 
234
175
  [MIT](LICENSE)
package/README.md CHANGED
@@ -1,13 +1,15 @@
1
- # DSH Grok Subscription — 在 DeepSeek Harness 使用 SuperGrok / X Premium 订阅
2
-
3
1
  <div align="center">
4
2
 
5
- **简体中文** · [English](https://github.com/BaronCyrus/dsh-grok-subscription/blob/main/README.en.md)
3
+ <img src="docs/assets/dsh-grok-mascot.png" width="220" height="220" alt="DSH Grok Subscription 吉祥物:彗星领航员">
4
+
5
+ # DSH Grok Subscription
6
6
 
7
- **把 SuperGrok / X Premium(Grok Build)订阅直接接入 DeepSeek Harness**
7
+ **简体中文** · [English](README.en.md)
8
8
 
9
- 复用官方 Grok Build CLI 的登录会话,不需要 `XAI_API_KEY`。
10
- 模型、推理档位和每周额度都留在 DSH 里。
9
+ **用 Grok Build 订阅,在 DSH 里编程、看图、切换推理档位。**
10
+
11
+ 复用官方 Grok Build CLI 登录会话,在 DeepSeek Harness 中选模型、带图提问、查看每周额度。
12
+ 无需另配 xAI 按量计费 API Key。
11
13
 
12
14
  [![CI](https://github.com/BaronCyrus/dsh-grok-subscription/actions/workflows/ci.yml/badge.svg)](https://github.com/BaronCyrus/dsh-grok-subscription/actions/workflows/ci.yml)
13
15
  [![npm](https://img.shields.io/npm/v/dsh-grok-subscription?logo=npm&label=npm)](https://www.npmjs.com/package/dsh-grok-subscription)
@@ -15,220 +17,157 @@
15
17
  [![MIT](https://img.shields.io/badge/license-MIT-111111.svg)](LICENSE)
16
18
  [![Star](https://img.shields.io/github/stars/BaronCyrus/dsh-grok-subscription?style=flat&logo=github&label=Star)](https://github.com/BaronCyrus/dsh-grok-subscription/stargazers)
17
19
 
18
- [三步开始](#三步开始) · [安装](#安装) · [参与贡献](CONTRIBUTING.md) · [更新与卸载](#更新与卸载)
20
+ [功能](#功能) · [安装](#安装) · [日常使用](#日常使用) · [界面预览](#界面预览) · [使用指南](#使用指南) · [更新与卸载](#更新与卸载)
19
21
 
20
22
  </div>
21
23
 
22
- <p align="center">
23
- <img src="docs/assets/grok-subscription-overview.webp" width="900" alt="在 DeepSeek Harness 中选择 Grok 4.7 并使用 SuperGrok 订阅进行多轮对话">
24
- </p>
25
-
26
- ## 三步开始
27
-
28
- 1. **安装插件**:在终端运行下面的命令;指定候选版本时填写完整的 `包名@版本`,例如 `dsh-grok-subscription@1.0.10`。
29
-
30
- ```sh
31
- dsh plugin --profile web add BaronCyrus/dsh-grok-subscription
32
- ```
24
+ <a id="核心优势"></a>
33
25
 
34
- 2. **登录订阅**:打开 **设置 → Grok 订阅**,点击 **CLI 登录** 或 **设备码登录**。插件会运行官方 `grok login`,把 CLI 打印的登录链接交给浏览器,并在面板里显示一次性验证码与可点的链接;授权完成后自动同步。已经自己跑过 `grok login` 的话,直接点 **从 Grok CLI 拉取** 即可,不需要粘贴任何 token。
35
- 3. **开始使用**:在模型选择器中选择 Grok 4.7 等模型。输入框旁的圆形徽章显示每周剩余额度,模型菜单里有推理档位。
36
-
37
- 安装或升级后需要重启 `dsh web`,否则会继续运行旧的 `lib/`。
38
-
39
- ## 核心优势
26
+ ## 功能
40
27
 
41
- | 能力 | 用户得到什么 |
28
+ | 能力 | 使用体验 |
42
29
  | --- | --- |
43
- | **订阅直连** | 复用官方 Grok Build CLI 会话,不需要 `XAI_API_KEY` |
44
- | **真实模型目录** | 登录后从 `/v1/models-v2` 读取账号实际可用的模型(如 `grok-4.7`、`grok-4.6`、`grok-4.5`);未登录时不暴露任何模型 |
45
- | **推理档位** | 模型选择器内置 `low` / `medium` / `high` / `xhigh` 子菜单,默认 `high`,与 Codex 的交互一致 |
46
- | **图片输入** | `grok-4.7` / `grok-4.7-fast` / `grok-4.6` 可直接粘贴图片提问,图片由宿主的附件服务按像素与体积预算归一化 |
47
- | **输入框额度** | 模型选择器旁的徽章直接显示每周剩余比例,悬停或点击查看「每周额度 剩余 N% · 重置于 M/D HH:mm」 |
48
- | **用量面板(实验性)** | 设置页显示服务端返回的已用与剩余百分比,读取失败时不猜数字、不虚构额度 |
49
- | **凭据留在本机** | 只在主机侧读取 `~/.grok/auth.json` 的短期 access token;不会把 token 交给浏览器 RPC |
50
- | **登录状态会刷新界面** | 登录、拉取或登出后自动派发 `llm/adapters-updated`,Chat 模型列表随之更新 |
51
- | **token 自动续期** | access token 只有 6 小时有效期;临近过期或遇到 401 时,插件会调用官方 `grok` CLI 刷新 `auth.json` 并自动重试一次,不需要手动重新登录 |
52
- | **失败可见** | 订阅路由不可用时明确报错,不会静默改用其他付费路由 |
53
-
54
- 这些能力共用同一份本机 Grok Build 登录。
55
-
56
- ## 实际界面
57
-
58
- <p align="center">
59
- <img src="docs/assets/settings-account.webp" width="820" alt="DSH 设置中的 Grok 订阅页面:登录状态、账号、登录按钮与凭据说明">
60
- </p>
61
-
62
- 上图为 **设置 → Grok 订阅** 主界面:顶部状态胶囊显示登录状态,账户卡片提供 CLI 登录、设备码登录、从 Grok CLI 拉取和登出,凭据读取方式收在可展开的「登录方式说明」里。样式沿用 DSH 自身的设计变量,因此跟随主题明暗切换。截图中的账号与时间均为演示数据。
63
-
64
- <p align="center">
65
- <img src="docs/assets/settings-usage.webp" width="820" alt="Grok 订阅设置页中的实验性用量面板:已用 6%、剩余约 94%">
66
- </p>
30
+ | **复用订阅登录** | 在设置页发起 CLI / 设备码登录,或拉取已有 Grok CLI 会话,无需手动粘贴 token |
31
+ | **模型目录同步** | 登录后优先读取账号模型目录;读取失败时可使用内置目录,未登录时不显示模型 |
32
+ | **推理档位** | 在模型菜单中选择可用档位,通常包含 `low` / `medium` / `high` / `xhigh`,默认优先使用 `high` |
33
+ | **图片输入** | 支持的模型可接收粘贴或附加的图片;设置页可检查当前运行通路与附件能力 |
34
+ | **每周额度** | 输入框徽章和设置页展示服务端返回的用量;额度接口为实验性,读取失败不编造数字 |
35
+ | **会话续期与更新** | 临近过期或认证拒绝时尝试通过官方 CLI 续期;设置页也可检查插件版本 |
36
+ | **凭据不返回浏览器** | access token 仅在 Host 侧使用;订阅失败不会静默改用其他付费模型路由 |
67
37
 
68
- 实验性用量面板来自未公开的订阅计费接口(`/v1/billing?format=credits`):剩余比例以进度条呈现,产品明细逐行列出。它仅供参考:接口可能随时变化或消失,读取失败时不会显示编造的百分比,也不影响聊天。
38
+ <a id="三步开始"></a>
39
+ <a id="准备-dsh"></a>
69
40
 
70
- ## 准备 DSH
41
+ ## 安装
71
42
 
72
- 本插件支持软件包元数据中记录的最新版 DeepSeek Harness,并需要一个具有 Grok Build 使用资格的 **SuperGrok 或 X Premium** 账号。
43
+ 需要 **DeepSeek Harness**、运行在同一台机器上的**官方 Grok Build CLI**,以及**当前具有 Grok Build 使用资格**的 SuperGrok / X Premium 账号。订阅名称本身不保证访问资格,以账号实际授权为准。
73
44
 
74
- - **已经能运行 `dsh`**:直接使用下面的标准命令;
75
- - **想按官方方式运行**:查看 [DeepSeek Harness 官方说明](https://github.com/deepseek-ai/deepseek-harness#run)。
45
+ 尚未安装 DSH,可查看 [DSH 官方说明](https://github.com/deepseek-ai/deepseek-harness#run)。版本要求与 CLI 路径说明见 [安装与兼容性](docs/guide.zh-CN.md#安装与兼容性)。
76
46
 
77
- 插件读取 `~/.grok/auth.json` 时较为严格:拒绝符号链接、拒绝组或其他用户可读的文件、拒绝非当前用户拥有的文件。如果权限不正确:
47
+ ### 1. 安装插件
78
48
 
79
49
  ```sh
80
- chmod 600 "${GROK_HOME:-$HOME/.grok}/auth.json"
50
+ dsh plugin --profile web add dsh-grok-subscription@latest
81
51
  ```
82
52
 
83
- ## 安装
53
+ 完成后,**手动重启正在运行的目标 DSH**。仅刷新浏览器不会重新加载 Host 中的适配器。
84
54
 
85
- ### DSH 标准命令
55
+ ### 2. 登录订阅
86
56
 
87
- ```sh
88
- dsh plugin --profile web add BaronCyrus/dsh-grok-subscription
89
- ```
90
-
91
- 也可以按 npm 上的已发布版本安装:
57
+ 打开 **设置 → Grok 订阅**,点击 **CLI 登录** 或 **设备码登录**,按浏览器和面板提示授权。已经运行过 `grok login`,可直接点击 **从 Grok CLI 拉取**。
92
58
 
93
- ```sh
94
- dsh plugin --profile web add dsh-grok-subscription@1.0.10
95
- ```
59
+ > 本插件依赖官方 Grok Build CLI 管理登录与续期,不是免 CLI 的方案。请勿粘贴 `XAI_API_KEY`,也不要把 `auth.json` 或 token 发到聊天、截图和公开 Issue 中。
96
60
 
97
- 目标选择、profile 锁、依赖解析和 bundle 激活均由 DSH 负责。
61
+ ### 3. 选择模型
98
62
 
99
- ### Headless
100
-
101
- 先在 Web 中完成登录并选择一次 Grok 模型,再把同一个插件安装到 DSH 的标准 Headless profile:
102
-
103
- ```sh
104
- dsh plugin --profile headless add BaronCyrus/dsh-grok-subscription
105
- dsh --profile headless "只回复:ok"
106
- ```
63
+ 在模型选择器中选择账号可用的 Grok 模型。按需要调整推理档位,开始对话或编程;模型旁的徽章显示成功读取到的每周余量。
107
64
 
108
65
  <details>
109
- <summary>官方 npm 方式(已安装 Node.js)</summary>
110
-
111
- 官方的 `npx @deepseek-ai/dsh web` 不会创建全局 `dsh` 命令,因此安装插件时也要保留完整的 `npx` 前缀:
66
+ <summary>检查安装 / 使用 npx / 安装指定版本</summary>
112
67
 
113
68
  ```sh
114
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web add BaronCyrus/dsh-grok-subscription
115
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web list dsh-grok-subscription --depth 0
116
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 --profile web --dump-config
69
+ dsh plugin --profile web list dsh-grok-subscription --depth 0
117
70
  ```
118
71
 
119
- </details>
120
-
121
- <details>
122
- <summary>已经能运行 <code>dsh</code> 时检查安装结果</summary>
72
+ 没有全局 `dsh` 命令时,保留你使用的完整 `npx` 前缀。以下使用项目元数据声明的基线版本作为示例:
123
73
 
124
74
  ```sh
125
- dsh plugin --profile web list dsh-grok-subscription --depth 0
126
- dsh --profile web --dump-config
75
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web add dsh-grok-subscription@latest
127
76
  ```
128
77
 
129
- 安装列表中应只有一个 `dsh-grok-subscription`,配置中应只有一个 `grok-build` 路由。
78
+ 固定 npm 版本、GitHub 来源安装、CLI 路径与 Headless 使用见 [完整使用指南](docs/guide.zh-CN.md)。
130
79
 
131
80
  </details>
132
81
 
133
- 安装完成后手动重启 DSH,然后:
82
+ ## 日常使用
134
83
 
135
- 1. 打开 **设置 → Grok 订阅**;
136
- 2. 登录具有 Grok Build 资格的账号(浏览器登录或设备码登录);
137
- 3. 在模型选择器中选择 Grok 模型。
84
+ **选模型与推理档位。** 登录后目录会刷新;以模型菜单提供的档位为准。目录读取失败时的内置列表不代表额外授予模型权限。
138
85
 
139
- ## 功能
86
+ **带图提问。** 在支持图片的模型下粘贴或附加图片。当前实现为 `grok-4.7`、`grok-4.7-build-fast`、`grok-4.6` 声明图片输入,不为 `grok-4.5` 声明;这指的是**读取图片,不是生成图片**。详见 [图片输入](docs/guide.zh-CN.md#图片输入)。
140
87
 
141
- - 复用官方 Grok Build CLI 会话登录,凭据保留在本机;账号以部分隐藏的邮箱区分;
142
- - 模型直接出现在 DSH 会话中,无需 `XAI_API_KEY`,也不向浏览器暴露 token;
143
- - 模型目录登录后自动拉取;读取失败或超时时回退到内置列表并记录错误,未登录时保持为空;
144
- - 模型菜单提供 `low` / `medium` / `high` / `xhigh` 推理档位,默认 `high`;
145
- - 输入框模型选择器旁显示每周剩余额度徽章,悬停或点击查看剩余比例与重置时间;
146
- - 设置页可查看服务端返回的用量与剩余百分比,失败时明确提示而不是显示猜测值;
147
- - 支持 CLI 登录、设备码登录、从 Grok CLI 拉取和登出;登录状态变化后 Chat 模型列表自动刷新;
148
- - access token 到期自动续期:临近 6 小时有效期或收到 401 时,调用官方 `grok` CLI 刷新会话并重试一次,不会中途要求手动重新登录;
149
- - 订阅路由不可用时明确报错,不会静默切换到其他付费路由;
150
- - 前缀缓存按 xAI 的自动缓存语义优化:同一 DSH 会话使用稳定的 `prompt_cache_key`,工具定义保持稳定顺序,回退适配器会保存并原样回放 `reasoning.encrypted_content`。缓存仍可能因服务端逐出而失效,插件不虚构命中率。
88
+ **查看每周额度。** 选择 `grok-build` 路由后,徽章展示成功读取的剩余比例;悬停或点击查看重置时间。完整信息在设置页查看,额度读取失败本身不会阻止聊天。
151
89
 
152
- ### 输入框额度
90
+ <a id="实际界面"></a>
91
+
92
+ ## 界面预览
153
93
 
154
94
  <p align="center">
155
- <img src="docs/assets/composer-quota.webp" width="820" alt="DSH 输入框:Grok 4.7 模型选择器旁的每周剩余额度徽章">
95
+ <img src="docs/assets/grok-subscription-overview.webp" width="900" alt="在 DSH 中选择 Grok 订阅模型并进行对话">
156
96
  </p>
157
97
 
158
- 仅当当前会话的 provider 为 `grok-build` 且用量读取成功时显示徽章;悬停或点击可查看「每周额度 剩余 N% · 重置于 M/D HH:mm」。徽章只反映服务端返回的每周额度;读取失败时徽章不显示,聊天不受影响。
159
-
160
- ### 图片输入
98
+ <p align="center">
99
+ <img src="docs/assets/composer-quota.webp" width="820" alt="Grok 模型选择器旁的每周剩余额度徽章">
100
+ </p>
161
101
 
162
- `grok-4.7`、`grok-4.7-fast` 与 `grok-4.6` 支持图片输入:在输入框粘贴或附加图片即可提问。图片由宿主的附件服务按像素与体积预算归一化后发送,超预算时降级为文本说明,而不是静默丢弃。
102
+ <details>
103
+ <summary>展开查看登录面板与实验性用量面板</summary>
163
104
 
164
- **两条通路都支持**:宿主官方 `pi-ai` 适配器可用时走官方实现,否则内置回退适配器自己读取附件字节并内联成 `input_image`。因此贴图能力不依赖宿主包的解析结果。设置页的「运行通路」会显示当前生效的是哪一条,以及图片输入是否可用 —— 遇到「当前模型不支持图片」时先看这一行。
105
+ <p align="center">
106
+ <img src="docs/assets/settings-account.webp" width="820" alt="Grok 订阅设置页中的账号状态与登录操作">
107
+ </p>
165
108
 
166
- > 若显示「内置回退」且贴图被拒,通常是 `dsh web` 更新后没有重启:客户端界面会随刷新更新,但主机端适配器是进程启动时加载的。
109
+ <p align="center">
110
+ <img src="docs/assets/settings-usage.webp" width="820" alt="Grok 订阅设置页中的实验性用量面板">
111
+ </p>
167
112
 
168
- `grok-4.5` **不在支持列表内**。实测给它一张纯红图片并询问颜色,它回答 "green",还把黄色方块描述成「带黑边的圆」——它在编造而不是看图。插件因此不为它声明图片能力,避免输出看起来自信却完全错误的答案。
113
+ 账号设置截图中的身份与时间为演示数据。用量截图仅说明界面,不代表任何账号的固定额度。
169
114
 
170
- ### 推理档位
115
+ </details>
171
116
 
172
- 选择 Grok 模型后,模型菜单里会出现推理档位子菜单:`low` / `medium` / `high` / `xhigh`,默认 `high`。档位通过 `model.reasoning`(`efforts` + `defaultEffort`)元数据提供,因此与 Codex 在 DSH 中的交互一致;具体可用档位以账号模型目录为准。
117
+ ## 使用指南
173
118
 
174
- ### 模型目录与登录状态
119
+ [完整使用指南](docs/guide.zh-CN.md) 包含 CLI 登录、模型目录、图片输入、额度限制、网络排查、Headless 使用和本地开发。
175
120
 
176
- 登录后插件从订阅代理读取账号实际可用的模型目录;未登录时不注册任何模型。读取失败或超时时回退到内置列表(`grok-4.7` / `grok-4.6` / `grok-4.5`)并在状态里记录错误,因此目录不会留空,也不会让插件启动卡住。
121
+ 常用入口:[登录与凭据](docs/guide.zh-CN.md#登录与凭据) · [图片输入](docs/guide.zh-CN.md#图片输入) · [故障排查](docs/guide.zh-CN.md#故障排查) · [参与贡献](CONTRIBUTING.md)。
177
122
 
178
123
  ## 更新与卸载
179
124
 
180
- ### 更新并检查
125
+ **更新 npm 安装:** 可在设置页检查版本;支持的 npm 安装可一键更新,也可以运行:
181
126
 
182
127
  ```sh
183
- dsh plugin --profile web update dsh-grok-subscription
184
- dsh plugin --profile web list dsh-grok-subscription --depth 0
185
- dsh --profile web --dump-config
128
+ dsh plugin --profile web add dsh-grok-subscription@latest
186
129
  ```
187
130
 
188
- ### 卸载
131
+ GitHub 来源安装可使用 `dsh plugin --profile web update dsh-grok-subscription`;本地 `link:` 安装应拉取对应仓库并重新构建,不要替换开发链接。
189
132
 
190
- 确认需要移除插件后再运行:
133
+ 桌面版由 Electron 应用独占 `desktop` profile,`dsh plugin --profile desktop …` 会被拒绝,因此桌面版的「更新插件」由插件自己在该 profile 目录中用 DSH 自带的 pnpm 安装精确版本;`1.1.1` 之前该按钮在桌面版必然失败,手动步骤见[更新与登出](docs/guide.zh-CN.md#更新与登出)。
134
+
135
+ **卸载:**
191
136
 
192
137
  ```sh
193
138
  dsh plugin --profile web remove dsh-grok-subscription
194
139
  ```
195
140
 
196
- 这些操作会保留 DSH profile、其他插件和 `~/.grok/auth.json` 中的登录信息。
197
-
198
- <details>
199
- <summary>官方 npm 备用方式</summary>
141
+ 完成后手动重启 DSH。卸载不会删除其他插件、整个 profile 或 Grok CLI 的 `auth.json`,也不等于从官方 CLI 登出;清理范围见 [更新与登出](docs/guide.zh-CN.md#更新与登出)。
200
142
 
201
- ```sh
202
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web update dsh-grok-subscription
203
- npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web remove dsh-grok-subscription
204
- ```
143
+ ## 常见问题
205
144
 
206
- </details>
145
+ **模型列表为空?** 先确认官方 Grok CLI 已完成订阅登录,再在设置页点击「从 Grok CLI 拉取」。只有 API Key 的 CLI 配置不等于订阅登录。
207
146
 
208
- ## 常见问题
147
+ **登录或请求超时?** 检查 DSH 所在机器能否连接账号与订阅服务,以及启动环境的代理设置。网络、登录状态和服务端异常都可能导致失败,不要直接认定为额度耗尽。见 [故障排查](docs/guide.zh-CN.md#故障排查)。
209
148
 
210
- - **`dsh` 无法识别**:官方 npm 方式本来就不会创建全局 `dsh` 命令,请使用上面的完整 `npx -y @deepseek-ai/dsh@0.1.5-rc.2 ...` 命令;
211
- - **模型列表是空的**:未登录时插件不暴露任何模型。先完成登录,再点 **从 Grok 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
- - **升级后界面没变化**:插件会继续运行旧的 `lib/`,请重新安装插件并重启 `dsh web`,然后硬刷新(Ctrl+Shift+R);
214
- - **提示 `auth.json` 权限不正确**:按上面的 `chmod 600` 处理;插件拒绝读取符号链接或组/其他用户可读的文件;
215
- - **出现「没有回复」**:请升级到 `1.0.1` 或更高版本。`1.0.0` 存在一个缺陷:工具调用轮次会因流片段无法无损序列化而整轮中止,界面上完全没有回复。
216
- - **聊天或用量提示 401「Invalid or expired credentials」**:Grok 的 access token 只有约 6 小时有效期,过期后聊天和用量会一起失败。`1.0.5` 起插件会自动调用官方 CLI 续期;更早版本请先运行任意 `grok` 命令(如 `grok models`)刷新 `~/.grok/auth.json`,再点面板里的「从 Grok CLI 拉取」。
149
+ **更新后不能带图?** 完整重启 DSH,检查模型是否在图片支持列表,以及设置页的「运行通路」是否显示附件能力可用。
217
150
 
218
151
  ## 边界与支持
219
152
 
220
- Grok 订阅后端和 DSH 可能独立变化;本项目为社区项目,与 DeepSeek、xAI 无隶属或背书关系。
153
+ 本项目是社区插件,与 DeepSeek、xAI 无隶属或背书关系。模型访问、推理档位和订阅额度由账号与服务端决定;本插件不授予额外权益。
154
+
155
+ 用量面板依赖未公开的订阅计费接口,属于**实验性能力**,可能因上游变化而不可用。凭据不返回浏览器不代表离线运行:模型请求仍发送到 Grok 订阅服务。
221
156
 
222
- 敏感问题请先阅读 [SECURITY.md](SECURITY.md)。问题反馈请使用 [Issues](https://github.com/BaronCyrus/dsh-grok-subscription/issues)。
157
+ 安全说明见 [SECURITY.md](SECURITY.md),问题反馈见 [Issues](https://github.com/BaronCyrus/dsh-grok-subscription/issues)。不要公开登录文件、token、原始账号响应或完整登录回调。
223
158
 
224
- ### 开发检查
159
+ ## 本地开发
225
160
 
226
161
  ```sh
227
- npm install
162
+ git clone https://github.com/BaronCyrus/dsh-grok-subscription.git
163
+ cd dsh-grok-subscription
164
+ npm ci
228
165
  npm test
229
166
  npm run build
230
167
  ```
231
168
 
232
- `lib/` 是提交进仓库的构建产物,改动 `src/` 后请运行 `npm run build`。
169
+ `lib/` 是已提交的构建产物,修改 `src/` 后应重新构建,不要手动编辑。开发与验证要求见 [CONTRIBUTING.md](CONTRIBUTING.md)。
170
+
171
+ ## License
233
172
 
234
173
  [MIT](LICENSE)
Binary file
@@ -0,0 +1,154 @@
1
+ # Grok subscription user guide
2
+
3
+ [Project home](../README.en.md) · [简体中文](guide.zh-CN.md) · **English**
4
+
5
+ For quick setup, see the [README](../README.en.md#install). This guide covers dependencies, capability limits, and troubleshooting.
6
+
7
+ ## Installation and compatibility
8
+
9
+ You need DeepSeek Harness, the official Grok Build CLI, and an account with Grok Build access. The plugin declares Node.js `^22.19.0 || >=24.0.0`; DSH peers use `^0.1.5-rc.2`. See [package.json](../package.json) for the full requirements. Declared compatibility is not a claim that every version has passed live verification.
10
+
11
+ **Install from npm:**
12
+
13
+ ```sh
14
+ dsh plugin --profile web add dsh-grok-subscription@latest
15
+ dsh plugin --profile web list dsh-grok-subscription --depth 0
16
+ ```
17
+
18
+ For reproducibility, pin a published version, for example:
19
+
20
+ ```sh
21
+ dsh plugin --profile web add dsh-grok-subscription@1.1.1
22
+ ```
23
+
24
+ **Install from GitHub:**
25
+
26
+ ```sh
27
+ dsh plugin --profile web add BaronCyrus/dsh-grok-subscription
28
+ ```
29
+
30
+ The GitHub branch and published npm package may differ. Choose an installation source deliberately; a source commit does not mean a new npm version has been published.
31
+
32
+ If you launch DSH with `npx` and have no global `dsh` command, retain the full prefix for plugin operations. This example uses the baseline declared in the package:
33
+
34
+ ```sh
35
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web add dsh-grok-subscription@latest
36
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web list dsh-grok-subscription --depth 0
37
+ ```
38
+
39
+ Restart the target DSH instance after installation. For local diagnosis, `dsh --profile web --dump-config` should show one `grok-build` route. Redact sensitive settings and personal paths before sharing diagnostics; do not post the full configuration.
40
+
41
+ ## Sign-in and credentials
42
+
43
+ **The official Grok Build CLI must be available on the DSH Host**, not just on the phone or another computer viewing the Web UI. The plugin checks `DSH_GROK_BIN`, then `${GROK_HOME:-$HOME/.grok}/bin/grok`, then `grok` on `PATH`. See [session.js](../src/session.js).
44
+
45
+ Use **CLI login** or **Device-code login** in Settings. The plugin invokes the official CLI and shows the available authorization link and one-time code in the panel. Alternatively, run this locally:
46
+
47
+ ```sh
48
+ grok login
49
+ ```
50
+
51
+ After authorizing, select **Pull from Grok CLI**. An `XAI_API_KEY`-only configuration is not a Grok Build subscription session. Never copy `auth.json`, access tokens, or refresh tokens into chats or public reports.
52
+
53
+ The plugin reads `${GROK_HOME:-$HOME/.grok}/auth.json` and rejects symlinks, non-regular files, and unsafe ownership or permissions. On macOS / Linux, after confirming the path and owner are correct, fix permission bits with:
54
+
55
+ ```sh
56
+ chmod 600 "${GROK_HOME:-$HOME/.grok}/auth.json"
57
+ ```
58
+
59
+ This does not fix an incorrect owner or make a symlink safe. The plugin itself does not write the file; the official CLI manages the session file and renewal. DSH stores only the short-lived access token it needs, without returning tokens through browser RPC. See [SECURITY.md](../SECURITY.md).
60
+
61
+ ## Model catalog and reasoning
62
+
63
+ After sign-in, the plugin prefers the catalog from `/v1/models-v2`; while signed out, models are empty. A failed, timed-out, or empty catalog read uses the built-in `grok-4.7` / `grok-4.6` / `grok-4.5` list and records the error. **This is a catalog fallback, not a different paid service, and listed models are not guaranteed entitlements.**
64
+
65
+ Reasoning options follow model metadata. The implementation recognizes `low` / `medium` / `high` / `xhigh`, usually defaulting to `high`; the built-in `grok-4.5` entry has only the first three. Follow the actual menu and backend-supported choices. See [catalog.js](../src/catalog.js).
66
+
67
+ Login, pull, logout, and catalog refresh notify the model picker. Near a known token expiry, or after an authentication rejection, the plugin attempts renewal through the official CLI. If renewal fails, authorization may still be required again; uninterrupted sessions are not guaranteed.
68
+
69
+ ## Image input
70
+
71
+ The source currently advertises image input only for:
72
+
73
+ ```text
74
+ grok-4.7
75
+ grok-4.7-build-fast
76
+ grok-4.6
77
+ ```
78
+
79
+ These exact IDs come from `IMAGE_INPUT_MODEL_IDS` in [constants.js](../src/constants.js); `grok-4.5` is excluded. Image input is not image generation, and a model's name alone does not establish image support.
80
+
81
+ Paste or attach an image in the composer. DSH's attachment service processes it within pixel and byte budgets; over-budget images may degrade to a text description. Do not assume every image is sent at its original resolution.
82
+
83
+ Both the host's pi-ai adapter and the bundled fallback have image-handling paths, but both depend on the host attachment capability. The **Active path** row in Settings shows the adapter and whether image input is available. After an update, a refreshed browser can still be using an old adapter if the Host was not restarted.
84
+
85
+ ## Quota and caching
86
+
87
+ Usage is read through the undocumented `/v1/billing?format=credits` endpoint and is experimental. Settings displays the used and remaining percentages actually returned. Interface changes, network failures, or invalid authentication can make the data unavailable.
88
+
89
+ The composer badge appears only for `grok-build` with a successful usage read; hover or click for weekly quota and its reset time. Missing data does not mean zero quota. A failed read does not invent percentages or independently block chat.
90
+
91
+ For prefix caching, the plugin keeps a stable `prompt_cache_key` and tool ordering within a DSH session, and the bundled adapter preserves `reasoning.encrypted_content`. These are request-construction measures, not a guarantee of backend cache hits or quota savings. No invented hit rate is reported. See [adapter.js](../src/adapter.js).
92
+
93
+ ## Headless usage
94
+
95
+ First complete subscription sign-in through the Grok CLI on the same host and verify Web usage. Then install the plugin into the target Headless profile:
96
+
97
+ ```sh
98
+ dsh plugin --profile headless add dsh-grok-subscription@latest
99
+ ```
100
+
101
+ Confirm that this profile's model configuration selects a `grok-build` model the account can use, then run a one-shot interactive task:
102
+
103
+ ```sh
104
+ dsh --profile headless "reply with exactly: ok"
105
+ ```
106
+
107
+ That task makes a real model request and uses the selected service's quota; it is not an offline check. Selecting a model in Web is not proof that another profile is configured correctly.
108
+
109
+ ## Troubleshooting
110
+
111
+ **`dsh` not found.** Use the full `npx` prefix you use to launch DSH, or check the installed launcher's path.
112
+
113
+ **`grok` not found or no login window.** Check that the CLI is installed on the DSH Host and its process sees `DSH_GROK_BIN` / `PATH`. Look for a clickable login link in the panel. A browser failing to open does not by itself prove the authorization service is unreachable.
114
+
115
+ **`fetch failed` or `Billing request timed out`.** Check access to the account service and `cli-chat-proxy.grok.com` separately. When a proxy is needed, set standard `https_proxy` / `http_proxy` variables in DSH's launch environment or `~/.dsh/.env`, not the project directory's `.env`, then manually restart DSH. The plugin uses the host network setup rather than providing its own proxy service. Network conditions are one possibility; also check authentication and backend errors.
116
+
117
+ **Empty model list.** Complete subscription sign-in and select **Pull from Grok CLI**. Check for an API-key-only login entry and inspect catalog status without sharing raw responses.
118
+
119
+ **Chat or usage returns `401`.** Check the CLI session. If automatic renewal fails, run `grok login` again, authorize, and pull the session. Do not repeatedly paste an old token.
120
+
121
+ **Images rejected.** Check the supported IDs and attachment capability under **Active path**. Fully restart the Host after updating, then refresh the browser.
122
+
123
+ **Auth-file permission error.** Check the actual path, owner, symlink status, and permissions. `chmod 600` fixes permission bits only.
124
+
125
+ **No response on an old release.** Version `1.0.0` had a tool-call serialization defect fixed in `1.0.1`; older versions may also lack later renewal fixes. Update to the current published version before diagnosing a persistent problem rather than attributing every missing response to that old defect.
126
+
127
+ ## Updates and sign-out
128
+
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
+
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
+
140
+ Uninstall with `dsh plugin --profile web remove dsh-grok-subscription`. This leaves the profile, other plugins, and the CLI's `auth.json` intact.
141
+
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.
143
+
144
+ ## Local development
145
+
146
+ Follow [CONTRIBUTING.md](../CONTRIBUTING.md) to install locked dependencies, test, and build:
147
+
148
+ ```sh
149
+ npm ci
150
+ npm test
151
+ npm run build
152
+ ```
153
+
154
+ After source changes, regenerate tracked `lib/` rather than editing it manually. Passing tests and builds do not verify real sign-in, GUI behavior, or live model calls. Restart DSH manually before evaluating Host changes.
@@ -0,0 +1,154 @@
1
+ # Grok 订阅使用指南
2
+
3
+ [返回项目首页](../README.md) · **简体中文** · [English](guide.en.md)
4
+
5
+ 快速安装见 [README](../README.md#安装)。本指南说明实际依赖、能力边界和排查顺序。
6
+
7
+ ## 安装与兼容性
8
+
9
+ 需要 DeepSeek Harness、官方 Grok Build CLI,以及当前具有 Grok Build 使用资格的订阅账号。插件的 Node.js 要求为 `^22.19.0 || >=24.0.0`,DSH peer 声明以 [package.json](../package.json) 为准;其中 DSH 依赖使用 `^0.1.5-rc.2`。声明范围不等于所有版本都已经过实机验证。
10
+
11
+ **npm 安装:**
12
+
13
+ ```sh
14
+ dsh plugin --profile web add dsh-grok-subscription@latest
15
+ dsh plugin --profile web list dsh-grok-subscription --depth 0
16
+ ```
17
+
18
+ 需要可重复安装时,固定已发布版本,例如:
19
+
20
+ ```sh
21
+ dsh plugin --profile web add dsh-grok-subscription@1.1.1
22
+ ```
23
+
24
+ **GitHub 来源安装:**
25
+
26
+ ```sh
27
+ dsh plugin --profile web add BaronCyrus/dsh-grok-subscription
28
+ ```
29
+
30
+ GitHub 分支与 npm 发布版本可能不同;请明确选择安装来源,不要把某个源码提交当作已经发布的 npm 版本。
31
+
32
+ 如果 DSH 通过 `npx` 运行、没有全局 `dsh` 命令,插件操作也需要完整前缀。下面以包声明的基线版本为例:
33
+
34
+ ```sh
35
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web add dsh-grok-subscription@latest
36
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web list dsh-grok-subscription --depth 0
37
+ ```
38
+
39
+ 安装后手动重启目标 DSH。需要进一步检查时,在本机运行 `dsh --profile web --dump-config`,确认只有一个 `grok-build` 路由;分享诊断前先隐藏敏感配置与个人路径,不要公开整份配置。
40
+
41
+ ## 登录与凭据
42
+
43
+ **官方 Grok Build CLI 必须在 DSH Host 上可用**,不是只安装在访问网页的手机或另一台电脑上。插件按以下顺序寻找命令:`DSH_GROK_BIN` 指定的路径、`${GROK_HOME:-$HOME/.grok}/bin/grok`、系统 `PATH` 中的 `grok`。实现见 [session.js](../src/session.js)。
44
+
45
+ 可在设置页发起 **CLI 登录** 或 **设备码登录**;插件会调用官方 CLI,并将可用的授权链接和一次性验证码显示在面板中。也可以自行在本机运行:
46
+
47
+ ```sh
48
+ grok login
49
+ ```
50
+
51
+ 授权完成后点击 **从 Grok CLI 拉取**。只有 `XAI_API_KEY` 的配置不属于 Grok Build 订阅登录。不要复制 `auth.json`、access token 或 refresh token 到聊天和公开问题中。
52
+
53
+ 插件读取 `${GROK_HOME:-$HOME/.grok}/auth.json`,拒绝符号链接、非普通文件及不安全的所有权或权限。在 macOS / Linux 上,确认路径和所有者正确后,可修正权限:
54
+
55
+ ```sh
56
+ chmod 600 "${GROK_HOME:-$HOME/.grok}/auth.json"
57
+ ```
58
+
59
+ 此命令不能修正错误所有者,也不能把符号链接变成安全文件。插件自身不写回这个文件;官方 CLI 会管理会话文件和续期。DSH 只保存使用所需的短期 access token,不把 token 通过浏览器 RPC 返回。详见 [SECURITY.md](../SECURITY.md)。
60
+
61
+ ## 模型目录与推理档位
62
+
63
+ 登录后优先从 `/v1/models-v2` 读取模型目录;未登录时模型为空。接口失败、超时或返回空目录时,使用内置 `grok-4.7` / `grok-4.6` / `grok-4.5` 列表,并记录目录错误。**回退的是目录,不是另一个付费服务;目录中的模型也不保证账号有调用权限。**
64
+
65
+ 推理档位按模型元数据提供。当前实现识别 `low` / `medium` / `high` / `xhigh`,通常默认 `high`;内置 `grok-4.5` 目录只包含前三档。以实际菜单与服务端接受的选项为准。实现见 [catalog.js](../src/catalog.js)。
66
+
67
+ 登录、拉取、登出和目录刷新会通知模型选择器更新。临近已知的 token 到期时间或遇到认证拒绝时,插件会尝试通过官方 CLI 续期;若失败,仍可能需要重新授权,不承诺会话永不失效。
68
+
69
+ ## 图片输入
70
+
71
+ 当前源码仅对以下模型声明图片输入:
72
+
73
+ ```text
74
+ grok-4.7
75
+ grok-4.7-build-fast
76
+ grok-4.6
77
+ ```
78
+
79
+ 准确 ID 来自 [constants.js](../src/constants.js) 的 `IMAGE_INPUT_MODEL_IDS`;`grok-4.5` 不在其中。图片输入并非图片生成,也不能从模型名称推断未知模型一定支持图片。
80
+
81
+ 在输入框粘贴或附加图片后,DSH 的附件服务会按像素与体积预算处理。图片超出可用预算时可能降级为文本说明;不要假设每张原图都以原始分辨率发出。
82
+
83
+ 宿主官方 pi-ai 适配器和内置回退适配器都有对应图片通路,但都依赖宿主附件能力。设置页的 **运行通路** 会显示当前适配器和图片输入是否可用。更新后只有界面刷新、Host 未重启时,可能仍运行旧适配器。
84
+
85
+ ## 额度与缓存
86
+
87
+ 用量通过未公开的 `/v1/billing?format=credits` 接口读取,属于实验性能力。设置页展示实际返回的已用和剩余比例;接口变化、网络异常或认证失效都可能使数据不可用。
88
+
89
+ 输入框徽章仅在当前 provider 为 `grok-build` 且用量读取成功时显示,悬停或点击查看每周余量与重置时间。缺失数据不是额度为零;读取失败不会编造百分比,也不会因为单独的额度读取故障阻止聊天。
90
+
91
+ 前缀缓存方面,插件为同一 DSH 会话保持稳定的 `prompt_cache_key` 和工具顺序,内置回退适配器保留 `reasoning.encrypted_content`。这些是请求构造措施,不保证服务端缓存命中或节省额度;项目不提供虚构的命中率。实现见 [adapter.js](../src/adapter.js)。
92
+
93
+ ## Headless 使用
94
+
95
+ 先在同一主机上完成 Grok CLI 订阅登录,并验证 Web 中可正常使用。然后把插件安装到目标 Headless profile:
96
+
97
+ ```sh
98
+ dsh plugin --profile headless add dsh-grok-subscription@latest
99
+ ```
100
+
101
+ 确认该 profile 的模型配置确实选择了 `grok-build` 下你有权使用的模型,再执行一次性交互任务:
102
+
103
+ ```sh
104
+ dsh --profile headless "只回复:ok"
105
+ ```
106
+
107
+ 这条任务命令会发起真实模型调用并使用所选服务的额度;它不是离线检查。Web 中选择模型,不应被当作另一个 profile 已正确配置的证明。
108
+
109
+ ## 故障排查
110
+
111
+ **找不到 `dsh`。** 使用你运行 DSH 时的完整 `npx` 前缀,或检查已安装启动器的命令路径。
112
+
113
+ **找不到 `grok` / 不弹出登录窗口。** 检查 CLI 是否安装在 DSH Host、`DSH_GROK_BIN` / `PATH` 是否对该进程可见,以及面板是否已显示可点击授权链接。浏览器没有弹出,不一定等于授权服务不可达。
114
+
115
+ **`fetch failed` / `Billing request timed out`。** 分别检查账号服务和 `cli-chat-proxy.grok.com` 的网络连接。需要代理时,在 DSH 启动环境或 `~/.dsh/.env` 中设置标准 `https_proxy` / `http_proxy`,而不是放进项目目录的 `.env`;再手动重启 DSH。插件沿用宿主网络配置,不提供单独代理服务。网络只是可能原因,还应检查认证和服务端错误。
116
+
117
+ **模型列表为空。** 先完成订阅登录并点击「从 Grok CLI 拉取」。检查是否只有 API-key 登录条目;查看目录状态,不要公开原始响应。
118
+
119
+ **聊天或用量返回 `401`。** 检查 CLI 会话是否有效。自动续期失败时,重新运行 `grok login`,完成授权后再次拉取。不要反复粘贴旧 token。
120
+
121
+ **图片被拒绝。** 对照图片支持列表,检查「运行通路」的附件能力,并在更新后完整重启 Host,再刷新网页。
122
+
123
+ **文件权限错误。** 检查 auth 文件的真实路径、所有者、是否为符号链接以及权限;`chmod 600` 仅解决权限位问题。
124
+
125
+ **旧版本发消息无回复。** `1.0.0` 存在已在 `1.0.1` 修正的工具调用序列化问题;旧版本也可能缺少后续续期修复。先更新到当前发布版,再定位仍然存在的问题,不要把所有无回复都归因于旧缺陷。
126
+
127
+ ## 更新与登出
128
+
129
+ npm 安装可在设置页更新,或运行 `dsh plugin --profile web add dsh-grok-subscription@latest`。GitHub 来源安装可运行 `dsh plugin --profile web update dsh-grok-subscription`。本地链接安装则拉取对应 checkout、测试并构建。更新后手动重启 DSH。
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
+
140
+ 卸载使用 `dsh plugin --profile web remove dsh-grok-subscription`。这不删除整个 profile、其他插件或 Grok CLI 的 `auth.json`。
141
+
142
+ 设置页「登出」清理的是插件侧会话状态,不等于撤销官方 CLI 会话。CLI 文件仍然存在时,之后重新拉取或启动可能再次同步登录;彻底结束官方会话应使用官方 CLI / 账号提供的登出与授权管理流程。不要靠删除整个 DSH profile 来处理一个账号。
143
+
144
+ ## 本地开发
145
+
146
+ 按 [CONTRIBUTING.md](../CONTRIBUTING.md) 安装锁定依赖、运行测试并构建:
147
+
148
+ ```sh
149
+ npm ci
150
+ npm test
151
+ npm run build
152
+ ```
153
+
154
+ 源码修改后重新生成已跟踪的 `lib/`,不要手工编辑产物。测试与构建通过不等于真实登录、界面和模型调用已验证;验证 Host 改动前需要手动重启 DSH。
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.20",
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.0.20",
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.0.20",
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",
@@ -13,10 +13,13 @@
13
13
  "files": [
14
14
  "lib",
15
15
  "docs/assets",
16
+ "docs/guide.zh-CN.md",
17
+ "docs/guide.en.md",
16
18
  "cordis.patch.yml",
17
19
  "README.md",
18
20
  "README.en.md",
19
21
  "CONTRIBUTING.md",
22
+ "CHANGELOG.md",
20
23
  "SECURITY.md",
21
24
  "LICENSE"
22
25
  ],