@beryl-so/cli 0.1.0 → 0.5.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/README.md CHANGED
@@ -12,9 +12,10 @@ that exposes every command to coding agents.
12
12
  npx @beryl-so/cli@latest init
13
13
  ```
14
14
 
15
- Signs you in, pins this repo to a project (creating it if needed — the agent starts
16
- exploring and authoring tests immediately), and wires the MCP server into Claude Code
17
- or Cursor. Safe to re-run.
15
+ Signs you in, pins this repo to a project (creating it if needed — and asking whether
16
+ you want to author tests locally with your own coding agent, the default, or let Beryl's
17
+ agent explore and author them), and wires the MCP server into Claude Code or Cursor.
18
+ Safe to re-run.
18
19
 
19
20
  ## Install
20
21
 
@@ -58,213 +59,267 @@ Every non-interactive command below is exposed as an MCP tool with the same name
58
59
 
59
60
  ### init
60
61
 
61
- | Command | Summary |
62
- | --- | --- |
63
- | `beryl init` | Set up Beryl in this repo — sign in, pin a project, wire up your coding agent |
62
+ Set up Beryl in this repo — sign in, pin a project, wire up your coding agent
63
+
64
+ | Command | Summary | MCP tool |
65
+ | --- | --- | --- |
66
+ | `beryl init` | Set up Beryl in this repo — sign in, pin a project, wire up your coding agent | — |
64
67
 
65
68
  ### login
66
69
 
67
- | Command | Summary |
68
- | --- | --- |
69
- | `beryl login` | Authenticate the CLI with your Beryl account |
70
+ Authenticate the CLI with your Beryl account
71
+
72
+ | Command | Summary | MCP tool |
73
+ | --- | --- | --- |
74
+ | `beryl login` | Authenticate the CLI with your Beryl account | — |
70
75
 
71
76
  ### logout
72
77
 
73
- | Command | Summary |
74
- | --- | --- |
75
- | `beryl logout` | Remove the stored token from the CLI config |
78
+ Remove the stored token from the CLI config
79
+
80
+ | Command | Summary | MCP tool |
81
+ | --- | --- | --- |
82
+ | `beryl logout` | Remove the stored token from the CLI config | `logout` |
76
83
 
77
84
  ### whoami
78
85
 
79
- | Command | Summary |
80
- | --- | --- |
81
- | `beryl whoami` | Show the signed-in account and the CLI's resolved defaults |
86
+ Show the signed-in account and the CLI's resolved defaults
87
+
88
+ | Command | Summary | MCP tool |
89
+ | --- | --- | --- |
90
+ | `beryl whoami` | Show the signed-in account and the CLI's resolved defaults | `whoami` |
82
91
 
83
92
  ### tokens
84
93
 
85
- | Command | Summary |
86
- | --- | --- |
87
- | `beryl tokens list` | List your personal access tokens |
88
- | `beryl tokens create <name>` | Mint a new personal access token (shown once) |
89
- | `beryl tokens revoke <token-id>` | Revoke a personal access token |
94
+ Manage the personal access tokens that authenticate the CLI and CI.
95
+
96
+ | Command | Summary | MCP tool |
97
+ | --- | --- | --- |
98
+ | `beryl tokens list` | List your personal access tokens | `tokens_list` |
99
+ | `beryl tokens create <name>` | Mint a new personal access token (shown once) | `tokens_create` |
100
+ | `beryl tokens revoke <token-id>` | Revoke a personal access token | `tokens_revoke` |
90
101
 
91
102
  ### workspaces
92
103
 
93
- | Command | Summary |
94
- | --- | --- |
95
- | `beryl workspaces list` | List workspaces you belong to |
96
- | `beryl workspaces get` | Show one workspace |
97
- | `beryl workspaces create <name>` | Create a workspace |
98
- | `beryl workspaces update` | Rename a workspace or change its visibility |
99
- | `beryl workspaces delete` | Delete a workspace and everything in it |
100
- | `beryl workspaces use <workspace>` | Set the default workspace for future commands |
101
- | `beryl workspaces history` | Show the workspace's action history (who did what, when) |
102
- | `beryl workspaces leave` | Leave a workspace you are a member of |
104
+ Create and manage workspaces, and pick the one your commands act on by default.
105
+
106
+ | Command | Summary | MCP tool |
107
+ | --- | --- | --- |
108
+ | `beryl workspaces list` | List workspaces you belong to | `workspaces_list` |
109
+ | `beryl workspaces get` | Show one workspace | `workspaces_get` |
110
+ | `beryl workspaces create <name>` | Create a workspace | `workspaces_create` |
111
+ | `beryl workspaces update` | Rename a workspace or change its visibility | `workspaces_update` |
112
+ | `beryl workspaces delete` | Delete a workspace and everything in it | `workspaces_delete` |
113
+ | `beryl workspaces use <workspace>` | Set the default workspace for future commands | `workspaces_use` |
114
+ | `beryl workspaces history` | Show the workspace's action history (who did what, when) | `workspaces_history` |
115
+ | `beryl workspaces leave` | Leave a workspace you are a member of | `workspaces_leave` |
103
116
 
104
117
  ### members
105
118
 
106
- | Command | Summary |
107
- | --- | --- |
108
- | `beryl members list` | List workspace members |
109
- | `beryl members set-role <user-id> <role>` | Change a member's role |
110
- | `beryl members remove <user-id>` | Remove a member from the workspace |
119
+ Manage who belongs to a workspace and their roles.
120
+
121
+ | Command | Summary | MCP tool |
122
+ | --- | --- | --- |
123
+ | `beryl members list` | List workspace members | `members_list` |
124
+ | `beryl members set-role <user-id> <role>` | Change a member's role | `members_set_role` |
125
+ | `beryl members remove <user-id>` | Remove a member from the workspace | `members_remove` |
111
126
 
112
127
  ### invites
113
128
 
114
- | Command | Summary |
115
- | --- | --- |
116
- | `beryl invites send <email>` | Invite someone to the workspace by email |
117
- | `beryl invites list` | List the workspace's outstanding invitations |
118
- | `beryl invites revoke <invitation-id>` | Revoke a pending invitation |
119
- | `beryl invites mine` | List invitations sent to you |
120
- | `beryl invites accept <invitation>` | Accept an invitation (by id, or by the token from the invite email) |
121
- | `beryl invites decline <invitation-id>` | Decline an invitation |
129
+ Send, list, and revoke workspace invitations, and accept ones sent to you.
130
+
131
+ | Command | Summary | MCP tool |
132
+ | --- | --- | --- |
133
+ | `beryl invites send <email>` | Invite someone to the workspace by email | `invites_send` |
134
+ | `beryl invites list` | List the workspace's outstanding invitations | `invites_list` |
135
+ | `beryl invites revoke <invitation-id>` | Revoke a pending invitation | `invites_revoke` |
136
+ | `beryl invites mine` | List invitations sent to you | `invites_mine` |
137
+ | `beryl invites accept <invitation>` | Accept an invitation (by id, or by the token from the invite email) | `invites_accept` |
138
+ | `beryl invites decline <invitation-id>` | Decline an invitation | `invites_decline` |
122
139
 
123
140
  ### projects
124
141
 
125
- | Command | Summary |
126
- | --- | --- |
127
- | `beryl projects list` | List projects in the workspace |
128
- | `beryl projects get` | Show one project, including its current exploration state |
129
- | `beryl projects create <url>` | Create a project — the agent starts exploring and authoring tests immediately |
130
- | `beryl projects rename <name>` | Rename a project |
131
- | `beryl projects delete` | Delete a project and all its tests and runs |
132
- | `beryl projects re-explore` | Send the agent back in run/heal existing tests and discover new flows |
133
- | `beryl projects report` | Aggregate quality report across recent runs (pass rates, flaky tests, trend) |
134
- | `beryl projects reusable-auth <url>` | Check whether a saved login can be reused for a URL before creating a project |
135
- | `beryl projects use <project>` | Set the default project for future commands |
142
+ Create and manage projects — a site Beryl explores, authors tests for, and runs.
143
+
144
+ `beryl projects` with no subcommand runs `projects list`.
145
+
146
+ | Command | Summary | MCP tool |
147
+ | --- | --- | --- |
148
+ | `beryl projects list` | List projects in the workspace | `projects_list` |
149
+ | `beryl projects get` | Show one project, including its current exploration state | `projects_get` |
150
+ | `beryl projects create <url>` | Create a project the agent starts exploring and authoring tests immediately | `projects_create` |
151
+ | `beryl projects rename <name>` | Rename a project | `projects_rename` |
152
+ | `beryl projects delete` | Delete a project and all its tests and runs | `projects_delete` |
153
+ | `beryl projects re-explore` | Send the agent back in — run/heal existing tests and discover new flows | `projects_re_explore` |
154
+ | `beryl projects report` | Aggregate quality report across recent runs (pass rates, flaky tests, trend) | `projects_report` |
155
+ | `beryl projects reusable-auth <url>` | Check whether a saved login can be reused for a URL before creating a project | `projects_reusable_auth` |
156
+ | `beryl projects use <project>` | Set the default project for future commands | `projects_use` |
136
157
 
137
158
  ### envs
138
159
 
139
- | Command | Summary |
140
- | --- | --- |
141
- | `beryl envs list` | List a project's environments |
142
- | `beryl envs get <env-id>` | Show one environment |
143
- | `beryl envs create <name> <url>` | Add an environment (e.g. staging) to a project |
144
- | `beryl envs update <env-id>` | Update an environment's name, URL, or auth settings |
145
- | `beryl envs delete <env-id>` | Delete an environment |
160
+ Manage a project's environments — the URLs and auth Beryl runs tests against.
161
+
162
+ | Command | Summary | MCP tool |
163
+ | --- | --- | --- |
164
+ | `beryl envs list` | List a project's environments | `envs_list` |
165
+ | `beryl envs get <env-id>` | Show one environment | `envs_get` |
166
+ | `beryl envs create <name> <url>` | Add an environment (e.g. staging) to a project | `envs_create` |
167
+ | `beryl envs update <env-id>` | Update an environment's name, URL, or auth settings | `envs_update` |
168
+ | `beryl envs delete <env-id>` | Delete an environment | `envs_delete` |
146
169
 
147
170
  ### schedule
148
171
 
149
- | Command | Summary |
150
- | --- | --- |
151
- | `beryl schedule get` | Show the project's daily/weekly run schedule |
152
- | `beryl schedule set` | Enable scheduled runs (daily, or weekly on a given day) |
153
- | `beryl schedule disable` | Turn scheduled runs off |
172
+ View and set the schedule on which Beryl runs a project's tests automatically.
173
+
174
+ | Command | Summary | MCP tool |
175
+ | --- | --- | --- |
176
+ | `beryl schedule get` | Show the project's daily/weekly run schedule | `schedule_get` |
177
+ | `beryl schedule set` | Enable scheduled runs (daily, or weekly on a given day) | `schedule_set` |
178
+ | `beryl schedule disable` | Turn scheduled runs off | `schedule_disable` |
154
179
 
155
180
  ### tests
156
181
 
157
- | Command | Summary |
158
- | --- | --- |
159
- | `beryl tests list` | List the project's tests with their latest result |
160
- | `beryl tests get <test-id>` | Show one test |
161
- | `beryl tests plan <test-id>` | Print a test's current step plan (JSON) |
162
- | `beryl tests create` | Create a test case from a JSON action plan — for tests authored locally, e.g. by your coding agent |
163
- | `beryl tests set-plan <test-id>` | Replace a test's step plan from a JSON file (creates a new version) |
164
- | `beryl tests recompile <test-id>` | Validate + verify an edited plan against the live site before persisting |
165
- | `beryl tests versions <test-id>` | List a test's version history |
166
- | `beryl tests version <test-id> <version-no>` | Show one specific version of a test (including its plan) |
167
- | `beryl tests diff <test-id> <from> <to>` | Diff two versions of a test's plan |
168
- | `beryl tests restore <test-id> <version-no>` | Restore a test to an earlier version |
169
- | `beryl tests reset <test-id>` | Discard user edits and return the test to its latest system-authored version |
170
- | `beryl tests heal <test-id> <state>` | Turn self-healing on or off for a test |
171
- | `beryl tests history <test-id>` | Pass/fail history, streak, and stability for a test |
172
- | `beryl tests script <test-id>` | Print the rendered Playwright spec for a test |
173
- | `beryl tests export <test-ids...>` | Export tests as Playwright .spec.ts files in a ZIP |
182
+ Author, inspect, version, and heal a project's tests — the checks Beryl runs on each run.
183
+
184
+ `beryl tests` with no subcommand runs `tests list`.
185
+
186
+ | Command | Summary | MCP tool |
187
+ | --- | --- | --- |
188
+ | `beryl tests lint` | Validate a plan JSON file offline, before sending it to the server | `tests_lint` |
189
+ | `beryl tests list` | List the project's tests with their latest result | `tests_list` |
190
+ | `beryl tests get <test-id>` | Show one test | `tests_get` |
191
+ | `beryl tests plan <test-id>` | Print a test's current step plan (JSON) | `tests_plan` |
192
+ | `beryl tests create` | Create a test case from a JSON action plan for tests authored locally, e.g. by your coding agent | `tests_create` |
193
+ | `beryl tests set-plan <test-id>` | Replace a test's step plan from a JSON file (creates a new version) | `tests_set_plan` |
194
+ | `beryl tests rename <test-id> <title>` | Rename a test | `tests_rename` |
195
+ | `beryl tests quarantine <test-id> <state>` | Mute a flaky test: it keeps running, but its failures stop failing the run | `tests_quarantine` |
196
+ | `beryl tests delete <test-id>` | Delete a test, its version history, and its results | `tests_delete` |
197
+ | `beryl tests recompile <test-id>` | Validate + verify an edited plan against the live site before persisting | `tests_recompile` |
198
+ | `beryl tests versions <test-id>` | List a test's version history | `tests_versions` |
199
+ | `beryl tests version <test-id> <version-no>` | Show one specific version of a test (including its plan) | `tests_version` |
200
+ | `beryl tests diff <test-id> <from> <to>` | Diff two versions of a test's plan | `tests_diff` |
201
+ | `beryl tests restore <test-id> <version-no>` | Restore a test to an earlier version | `tests_restore` |
202
+ | `beryl tests reset <test-id>` | Discard user edits and return the test to its latest system-authored version | `tests_reset` |
203
+ | `beryl tests heal <test-id> <state>` | Turn self-healing on or off for a test | `tests_heal` |
204
+ | `beryl tests history <test-id>` | Pass/fail history, streak, and stability for a test | `tests_history` |
205
+ | `beryl tests script <test-id>` | Print the rendered Playwright spec for a test | `tests_script` |
206
+ | `beryl tests export <test-ids...>` | Export tests as Playwright .spec.ts files in a ZIP | `tests_export` |
174
207
 
175
208
  ### runs
176
209
 
177
- | Command | Summary |
178
- | --- | --- |
179
- | `beryl runs trigger` | Trigger a test run (whole suite, a subset, or one environment) |
180
- | `beryl runs list` | List recent runs |
181
- | `beryl runs get <run-id>` | Show one run with its per-test results |
182
- | `beryl runs watch <run-id>` | Attach to a run and stream progress until it finishes |
183
- | `beryl runs cancel <run-id>` | Cancel an in-flight run |
184
- | `beryl runs report <run-id>` | Show the generated report for a run |
185
- | `beryl runs download <run-id>` | Download a run's full results as JSON |
186
- | `beryl runs explain <result-id>` | AI explanation of why a test result failed |
210
+ Trigger a run of a project's tests (e.g. in CI), then watch, inspect, and download results.
211
+
212
+ `beryl runs` with no subcommand runs `runs list`.
213
+
214
+ | Command | Summary | MCP tool |
215
+ | --- | --- | --- |
216
+ | `beryl runs trigger` | Trigger a test run (whole suite, a subset, or one environment) | `runs_trigger` |
217
+ | `beryl runs local <test-id>` | Run a banked test locally with your own Playwright (public flows) | `runs_local` |
218
+ | `beryl runs list` | List recent runs | `runs_list` |
219
+ | `beryl runs get <run-id>` | Show one run with its per-test results | `runs_get` |
220
+ | `beryl runs watch <run-id>` | Attach to a run and stream progress until it finishes | `runs_watch` |
221
+ | `beryl runs cancel <run-id>` | Cancel an in-flight run | `runs_cancel` |
222
+ | `beryl runs report <run-id>` | Show the generated report for a run | `runs_report` |
223
+ | `beryl runs download <run-id>` | Download a run's results, with its artifacts, to disk | `runs_download` |
224
+ | `beryl runs explain <result-id>` | Explain, with AI, why a test result failed | `runs_explain` |
187
225
 
188
226
  ### explorations
189
227
 
190
- | Command | Summary |
191
- | --- | --- |
192
- | `beryl explorations list` | List the agent's exploration passes for a project |
193
- | `beryl explorations get <exploration-id>` | Show one exploration: authored tests, abandoned flows, coverage, frontier |
194
- | `beryl explorations steps <exploration-id>` | List every step the agent took in an exploration |
195
- | `beryl explorations watch <exploration-id>` | Stream an exploration live watch the agent explore and author tests |
228
+ Inspect the agent's exploration runs — how it crawled a site and authored its tests.
229
+
230
+ | Command | Summary | MCP tool |
231
+ | --- | --- | --- |
232
+ | `beryl explorations list` | List the agent's exploration passes for a project | `explorations_list` |
233
+ | `beryl explorations get <exploration-id>` | Show one exploration: authored tests, abandoned flows, coverage, frontier | `explorations_get` |
234
+ | `beryl explorations steps <exploration-id>` | List every step the agent took in an exploration | `explorations_steps` |
235
+ | `beryl explorations watch <exploration-id>` | Stream an exploration live — watch the agent explore and author tests | `explorations_watch` |
196
236
 
197
237
  ### config
198
238
 
199
- | Command | Summary |
200
- | --- | --- |
201
- | `beryl config vars list` | List the project's config variables (visible to the agent during runs) |
202
- | `beryl config vars set <key> <value>` | Create or update a config variable |
203
- | `beryl config vars delete <key>` | Delete a config variable |
204
- | `beryl config secrets list` | List the project's secrets (values are never returned) |
205
- | `beryl config secrets set <key> <value>` | Create a secret (write-only; re-setting a key replaces it) |
206
- | `beryl config secrets delete <key>` | Delete a secret |
207
- | `beryl config files list` | List files uploaded for the agent to use (e.g. CSVs, upload fixtures) |
208
- | `beryl config files upload <file>` | Upload a file |
209
- | `beryl config files download <file-id>` | Get a short-lived download URL for a file |
210
- | `beryl config files delete <file-id>` | Delete an uploaded file |
239
+ Manage the variables, secrets, and files the agent can use while exploring and running.
240
+
241
+ | Command | Summary | MCP tool |
242
+ | --- | --- | --- |
243
+ | `beryl config vars list` | List the project's config variables (visible to the agent during runs) | `config_vars_list` |
244
+ | `beryl config vars set <key> <value>` | Create or update a config variable | `config_vars_set` |
245
+ | `beryl config vars delete <key>` | Delete a config variable | `config_vars_delete` |
246
+ | `beryl config secrets list` | List the project's secrets (values are never returned) | `config_secrets_list` |
247
+ | `beryl config secrets set <key> <value>` | Create a secret (write-only; re-setting a key replaces it) | `config_secrets_set` |
248
+ | `beryl config secrets delete <key>` | Delete a secret | `config_secrets_delete` |
249
+ | `beryl config files list` | List files uploaded for the agent to use (e.g. CSVs, upload fixtures) | `config_files_list` |
250
+ | `beryl config files upload <file>` | Upload a file | `config_files_upload` |
251
+ | `beryl config files download <file-id>` | Get a short-lived download URL for a file | `config_files_download` |
252
+ | `beryl config files delete <file-id>` | Delete an uploaded file | `config_files_delete` |
211
253
 
212
254
  ### credentials
213
255
 
214
- | Command | Summary |
215
- | --- | --- |
216
- | `beryl credentials list` | List the workspace's saved logins |
217
- | `beryl credentials get <credential-id>` | Show one saved login (status and freshness — never the session itself) |
218
- | `beryl credentials projects <credential-id>` | List the projects using a saved login |
219
- | `beryl credentials delete <credential-id>` | Delete a saved login |
220
- | `beryl credentials attach <credential-id>` | Attach a saved login to a project |
221
- | `beryl credentials detach` | Detach the project's saved login |
222
- | `beryl credentials recapture <credential-id>` | Start a re-capture for an expiring saved login (returns a live browser URL) |
223
- | `beryl credentials capture` | Capture a login for the project interactively: log in once in a real browser |
256
+ Manage saved logins Beryl reuses to test behind authentication, and attach them to projects.
257
+
258
+ | Command | Summary | MCP tool |
259
+ | --- | --- | --- |
260
+ | `beryl credentials list` | List the workspace's saved logins | `credentials_list` |
261
+ | `beryl credentials get <credential-id>` | Show one saved login (status and freshness — never the session itself) | `credentials_get` |
262
+ | `beryl credentials projects <credential-id>` | List the projects using a saved login | `credentials_projects` |
263
+ | `beryl credentials delete <credential-id>` | Delete a saved login | `credentials_delete` |
264
+ | `beryl credentials attach <credential-id>` | Attach a saved login to a project | `credentials_attach` |
265
+ | `beryl credentials detach` | Detach the project's saved login | `credentials_detach` |
266
+ | `beryl credentials recapture <credential-id>` | Start a re-capture for an expiring saved login (returns a live browser URL) | `credentials_recapture` |
267
+ | `beryl credentials capture` | Capture a login for the project interactively: log in once in a real browser | — |
224
268
 
225
269
  ### auth-capture
226
270
 
227
- | Command | Summary |
228
- | --- | --- |
229
- | `beryl auth-capture start` | Start a login-capture browser session for the project (non-interactive) |
230
- | `beryl auth-capture capture <session-id>` | Capture the session after the user has logged in via the live-view URL |
231
- | `beryl auth-capture refresh <session-id>` | Capture a refreshed session for a project whose login is expiring |
232
- | `beryl auth-capture release <session-id>` | Release a login-capture browser session without capturing |
271
+ Drive a browser session that captures a target-site login for Beryl to reuse.
272
+
273
+ | Command | Summary | MCP tool |
274
+ | --- | --- | --- |
275
+ | `beryl auth-capture start` | Start a login-capture browser session for the project (non-interactive) | `auth_capture_start` |
276
+ | `beryl auth-capture capture <session-id>` | Capture the session after the user has logged in via the live-view URL | `auth_capture_capture` |
277
+ | `beryl auth-capture refresh <session-id>` | Capture a refreshed session for a project whose login is expiring | `auth_capture_refresh` |
278
+ | `beryl auth-capture release <session-id>` | Release a login-capture browser session without capturing | `auth_capture_release` |
233
279
 
234
280
  ### account
235
281
 
236
- | Command | Summary |
237
- | --- | --- |
238
- | `beryl account get` | Show your account profile |
239
- | `beryl account update` | Update your profile |
240
- | `beryl account deletion-preview` | Preview what deleting your account would remove or leave |
282
+ View and update your personal account profile.
283
+
284
+ | Command | Summary | MCP tool |
285
+ | --- | --- | --- |
286
+ | `beryl account get` | Show your account profile | `account_get` |
287
+ | `beryl account update` | Update your profile | `account_update` |
288
+ | `beryl account deletion-preview` | Preview what deleting your account would remove or leave | `account_deletion_preview` |
241
289
 
242
290
  ### feedback
243
291
 
244
- | Command | Summary |
245
- | --- | --- |
246
- | `beryl feedback send <message>` | Send product feedback to the Beryl team |
292
+ Send product feedback to the Beryl team.
293
+
294
+ | Command | Summary | MCP tool |
295
+ | --- | --- | --- |
296
+ | `beryl feedback send <message>` | Send product feedback to the Beryl team | `feedback_send` |
247
297
 
248
298
  ### billing
249
299
 
250
- | Command | Summary |
251
- | --- | --- |
252
- | `beryl billing usage` | Show plan usage: services and weekly AI units |
253
- | `beryl billing subscription` | Show the workspace's subscription |
254
- | `beryl billing invoices` | List recent invoices |
255
- | `beryl billing portal` | Get a Stripe billing-portal link for the workspace |
300
+ Review a workspace's plan usage, subscription, and invoices.
301
+
302
+ | Command | Summary | MCP tool |
303
+ | --- | --- | --- |
304
+ | `beryl billing usage` | Show plan usage: services and weekly AI units | `billing_usage` |
305
+ | `beryl billing subscription` | Show the workspace's subscription | `billing_subscription` |
306
+ | `beryl billing invoices` | List recent invoices | `billing_invoices` |
307
+ | `beryl billing portal` | Get a Stripe billing-portal link for the workspace | `billing_portal` |
256
308
 
257
309
  ### mcp
258
310
 
259
- | Command | Summary |
260
- | --- | --- |
261
- | `beryl mcp` | Run the Beryl MCP server (stdio) — every CLI command as an agent tool |
311
+ Run the Beryl MCP server (stdio) — every CLI command as an agent tool
312
+
313
+ | Command | Summary | MCP tool |
314
+ | --- | --- | --- |
315
+ | `beryl mcp` | Run the Beryl MCP server (stdio) — every CLI command as an agent tool | — |
262
316
 
263
317
  Run `beryl <command> --help` for flags and examples.
264
318
 
265
319
  ## Global flags
266
320
 
321
+ - `-V, --version` — Print the CLI version and exit
267
322
  - `--json` — Print machine-readable JSON (NDJSON for streams)
268
323
  - `--api-url` — API base URL (default https://api.beryl.so)
269
324
  - `--token` — Personal access token (overrides config/BERYL_API_KEY)
270
- - `--help` — Show help
325
+ - `-h, --help` — Show help
@@ -4,8 +4,10 @@ import { createContext } from "../context.js";
4
4
  import { CliError, EXIT_OK, EXIT_USAGE, UsageError } from "../errors.js";
5
5
  import { ApiClient } from "../http.js";
6
6
  import { autoFormat, bold, cyan, dim } from "../output.js";
7
- import { commandGroups, findCommand } from "../registry/index.js";
7
+ import { commandGroups, findCommand, groupSummary } from "../registry/index.js";
8
+ import { mcpToolFor } from "./mcp.js";
8
9
  export const GLOBAL_FLAGS = [
10
+ { name: "version", description: "Print the CLI version and exit", alias: "V" },
9
11
  { name: "json", description: "Print machine-readable JSON (NDJSON for streams)" },
10
12
  { name: "api-url", description: "API base URL (default https://api.beryl.so)", value: true },
11
13
  { name: "token", description: "Personal access token (overrides config/BERYL_API_KEY)", value: true },
@@ -90,6 +92,10 @@ export function parseArgv(spec, tokens) {
90
92
  throw new UsageError(`Unknown flag --${name} for \`beryl ${spec.name}\``);
91
93
  }
92
94
  }
95
+ // `--help` wins over every completeness check below: you ask for help precisely when you
96
+ // don't yet know which flags/args the command needs.
97
+ if (help)
98
+ return { input: { args: {}, flags }, json, apiUrl, token, help };
93
99
  for (const f of specFlags) {
94
100
  if (flags[f.name] === undefined && f.default !== undefined)
95
101
  flags[f.name] = f.default;
@@ -133,10 +139,25 @@ export function usageLine(spec) {
133
139
  .join(" ");
134
140
  return `Usage: beryl ${spec.name}${args ? " " + args : ""} [flags]`;
135
141
  }
142
+ function globalFlagLabel(flag) {
143
+ const value = "value" in flag && flag.value ? " <value>" : "";
144
+ const long = `--${flag.name}${value}`;
145
+ return "alias" in flag && flag.alias ? `-${flag.alias}, ${long}` : long;
146
+ }
147
+ function globalFlagLines() {
148
+ const lines = [bold("Global options:")];
149
+ for (const g of GLOBAL_FLAGS) {
150
+ lines.push(` ${cyan(globalFlagLabel(g).padEnd(24))} ${g.description}`);
151
+ }
152
+ return lines;
153
+ }
136
154
  export function commandHelp(spec) {
137
155
  const lines = [spec.summary, "", usageLine(spec)];
138
156
  if (spec.description)
139
157
  lines.push("", spec.description);
158
+ const tool = mcpToolFor(spec);
159
+ if (tool)
160
+ lines.push("", `${dim("MCP tool:")} ${cyan(tool)}`);
140
161
  if (spec.args?.length) {
141
162
  lines.push("", bold("Arguments:"));
142
163
  for (const a of spec.args)
@@ -150,10 +171,7 @@ export function commandHelp(spec) {
150
171
  lines.push(` ${cyan(label.padEnd(24))} ${f.description}${suffix}`);
151
172
  }
152
173
  }
153
- lines.push("", bold("Global flags:"));
154
- for (const g of GLOBAL_FLAGS) {
155
- lines.push(` ${cyan(("--" + g.name).padEnd(24))} ${g.description}`);
156
- }
174
+ lines.push("", ...globalFlagLines());
157
175
  if (spec.examples?.length) {
158
176
  lines.push("", bold("Examples:"));
159
177
  for (const e of spec.examples)
@@ -167,24 +185,39 @@ export function rootHelp() {
167
185
  "",
168
186
  "Usage: beryl <command> [args] [flags]",
169
187
  "",
188
+ bold("Commands:"),
170
189
  ];
171
190
  for (const [group, specs] of commandGroups()) {
172
- if (specs.length === 1 && specs[0].name === group) {
173
- lines.push(` ${cyan(group.padEnd(14))} ${specs[0].summary}`);
191
+ const single = specs.length === 1 && specs[0].name === group;
192
+ const purpose = single ? specs[0].summary : groupSummary(specs);
193
+ lines.push(` ${cyan(group.padEnd(14))} ${purpose ?? ""}`.trimEnd());
194
+ if (single) {
195
+ const tool = mcpToolFor(specs[0]);
196
+ if (tool)
197
+ lines.push(` ${" ".repeat(14)} ${dim("MCP tool " + tool)}`);
174
198
  }
175
199
  else {
176
- lines.push(` ${cyan(group.padEnd(14))} ${specs
177
- .map((s) => s.name.split(" ").slice(1).join(" "))
178
- .join(", ")}`);
200
+ const subs = specs.map((s) => s.name.split(" ").slice(1).join(" ")).join(", ");
201
+ const toolPrefix = group.replace(/-/g, "_");
202
+ const tools = specs.some((s) => mcpToolFor(s)) ? ` · ${dim("MCP tools " + toolPrefix + "_*")}` : "";
203
+ lines.push(` ${" ".repeat(14)} ${dim(subs)}`, ` ${" ".repeat(14)} ${dim(`beryl ${group} --help`)}${tools}`);
179
204
  }
180
205
  }
206
+ lines.push("", ...globalFlagLines());
181
207
  lines.push("", `Run ${cyan("beryl <command> --help")} for details, ${cyan("beryl login")} to get started.`, `Docs: ${cyan("https://beryl.so/docs/cli")}`);
182
208
  return lines.join("\n");
183
209
  }
184
210
  function groupHelp(group, specs) {
185
211
  const lines = [`${bold("beryl " + group)} — subcommands:`, ""];
212
+ const purpose = groupSummary(specs);
213
+ if (purpose)
214
+ lines.push(purpose, "");
186
215
  for (const spec of specs) {
187
- lines.push(` ${cyan(spec.name.padEnd(28))} ${spec.summary}`);
216
+ const suffix = spec.groupDefault ? dim(` (default — \`beryl ${group}\` runs this)`) : "";
217
+ lines.push(` ${cyan(spec.name.padEnd(28))} ${spec.summary}${suffix}`);
218
+ const tool = mcpToolFor(spec);
219
+ if (tool)
220
+ lines.push(` ${" ".repeat(28)} ${dim("MCP tool " + tool)}`);
188
221
  }
189
222
  lines.push("", `Run ${cyan(`beryl ${group} <subcommand> --help`)} for details.`);
190
223
  return lines.join("\n");
@@ -197,7 +230,7 @@ export async function runCli(argv) {
197
230
  break;
198
231
  words.push(tok);
199
232
  }
200
- if (argv.includes("--version") || argv[0] === "version") {
233
+ if (argv.includes("--version") || argv.includes("-V") || argv[0] === "version") {
201
234
  process.stdout.write(cliVersion() + "\n");
202
235
  return EXIT_OK;
203
236
  }
@@ -207,15 +240,25 @@ export async function runCli(argv) {
207
240
  }
208
241
  if (words.length === 0) {
209
242
  process.stdout.write(rootHelp() + "\n");
210
- return argv.length === 0 || argv.includes("--help") || argv.includes("-h")
243
+ return rest.length === 0 || rest.includes("--help") || rest.includes("-h")
211
244
  ? EXIT_OK
212
245
  : EXIT_USAGE;
213
246
  }
247
+ // A group of subcommands, as opposed to a single-word command like `init`, which
248
+ // commandGroups() also keys under its own name.
249
+ const groupSpecs = words.length === 1 ? commandGroups().get(words[0]) : undefined;
250
+ const group = groupSpecs && !(groupSpecs.length === 1 && groupSpecs[0].name === words[0])
251
+ ? groupSpecs
252
+ : undefined;
253
+ // `beryl tests --help` asks about the group, not about the subcommand `beryl tests`
254
+ // happens to default to — so group help wins over the default's own help.
255
+ if (group && (rest.includes("--help") || rest.includes("-h"))) {
256
+ process.stdout.write(groupHelp(words[0], group) + "\n");
257
+ return EXIT_OK;
258
+ }
214
259
  const found = findCommand(words);
215
260
  if (!found) {
216
- const groups = commandGroups();
217
- const group = groups.get(words[0]);
218
- if (group && words.length === 1) {
261
+ if (group) {
219
262
  process.stdout.write(groupHelp(words[0], group) + "\n");
220
263
  return EXIT_OK;
221
264
  }
@@ -245,7 +288,7 @@ export async function runCli(argv) {
245
288
  if (parsed.token)
246
289
  config.token = parsed.token;
247
290
  const client = new ApiClient(config.apiUrl, config.token);
248
- const ctx = createContext({ client, config, json: parsed.json });
291
+ const ctx = createContext({ client, config, json: parsed.json, mcp: false });
249
292
  try {
250
293
  const result = (await spec.run(ctx, parsed.input)) ?? {};
251
294
  if (parsed.json) {