dsh-grok-subscription 1.0.19 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # Changelog
2
+
3
+ ## 1.1.0 — 2026-09-28
4
+
5
+ - Add the original Comet Navigator mascot and align the Chinese/English homepages around features, installation, daily use, screenshots, and maintenance.
6
+ - Add bilingual usage guides covering the official CLI requirement, subscription sessions, model access, image input, experimental quota, troubleshooting, and safe removal.
7
+ - Ship the usage guides alongside the existing screenshots and mascot in npm and release archives.
8
+ - Align the manifest, lockfile root, Settings subtitle, and pinned install examples on 1.1.0; add release metadata and documentation packaging regression checks.
9
+ - Clarify the image-input model ID as `grok-4.7-build-fast`. This is a documentation correction, not a new image-processing capability.
10
+ - No model-routing, authentication, proxy, quota, or dependency behavior changes. This release carries forward the runtime fixes in 1.0.20.
11
+
12
+ 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,173 @@
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
41
+ ## Install
71
42
 
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.
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.
73
44
 
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).
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).
76
46
 
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:
47
+ ### 1. Install the plugin
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
- ## Install
53
+ Then **manually restart the target DSH instance**. Refreshing the browser alone does not reload the Host adapter.
84
54
 
85
- ### Standard DSH command
55
+ ### 2. Sign in
86
56
 
87
- ```sh
88
- dsh plugin --profile web add BaronCyrus/dsh-grok-subscription
89
- ```
90
-
91
- You can also install the version published on npm:
92
-
93
- ```sh
94
- dsh plugin --profile web add dsh-grok-subscription@1.0.10
95
- ```
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**.
96
58
 
97
- DSH handles target selection, the profile lock, dependency resolution, and bundle activation.
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.
98
60
 
99
- ### Headless
61
+ ### 3. Select a model
100
62
 
101
- Sign in and select a Grok model once in the Web UI, then install the same plugin into the standard DSH Headless profile:
102
-
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).
87
+
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.
140
89
 
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.
90
+ <a id="product-screen"></a>
151
91
 
152
- ### Composer quota
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.
189
132
 
190
- Confirm you want the plugin removed, then run:
133
+ **Uninstall:**
191
134
 
192
135
  ```sh
193
136
  dsh plugin --profile web remove dsh-grok-subscription
194
137
  ```
195
138
 
196
- These operations keep the DSH profile, other plugins, and the sign-in stored in `~/.grok/auth.json`.
139
+ 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
140
 
198
- <details>
199
- <summary>Official npm fallback</summary>
141
+ <a id="troubleshooting"></a>
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
+ ## FAQ
205
144
 
206
- </details>
145
+ **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
146
 
208
- ## Troubleshooting
147
+ **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
148
 
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. Add `GROK_PROXY=http://127.0.0.1:10808` to `~/.dsh/.env`: it applies only to **this plugin's own Grok requests** (the host undici's `fetch`; the process-wide dispatcher is never replaced) and to the **`grok` CLI** it spawns. Every other plugin, DSH itself, and every other provider keep the host's original `fetch`. To proxy the whole Harness, set the standard `https_proxy` (in `~/.dsh/.env`, never in a project `.env`): `@deepseek-ai/dsh-http-proxy` takes over and this plugin adds no tunnel of its own. 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**.
149
+ **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
150
 
218
151
  ## Scope and support
219
152
 
220
- The Grok subscription backend and DSH can change independently; this is a community project with no affiliation or endorsement from DeepSeek or xAI.
153
+ 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.
154
+
155
+ 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
156
 
222
- For sensitive issues read [SECURITY.md](SECURITY.md) first. For bug reports use [Issues](https://github.com/BaronCyrus/dsh-grok-subscription/issues).
157
+ 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
158
 
224
- ### Development checks
159
+ ## Local development
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/` is a committed build artifact, so run `npm run build` after changing `src/`.
169
+ `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.
170
+
171
+ ## License
233
172
 
234
173
  [MIT](LICENSE)