@beryl-so/cli 0.29.0 → 0.33.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 +70 -55
- package/dist/beryl-test-skill.js +3 -0
- package/dist/commands/accounts.js +6 -6
- package/dist/commands/auth.js +5 -5
- package/dist/commands/config-vars.js +5 -5
- package/dist/commands/environments.js +91 -25
- package/dist/commands/explorations.js +3 -3
- package/dist/commands/groups.js +69 -0
- package/dist/commands/health.js +1 -1
- package/dist/commands/init.js +8 -8
- package/dist/commands/mailboxes.js +6 -6
- package/dist/commands/mcp.js +3 -3
- package/dist/commands/projects.js +5 -5
- package/dist/commands/runs.js +83 -23
- package/dist/commands/tests.js +112 -32
- package/dist/commands/util.js +20 -0
- package/dist/commands/watch.js +2 -1
- package/dist/registry/index.js +2 -0
- package/package.json +2 -2
package/dist/commands/tests.js
CHANGED
|
@@ -7,7 +7,7 @@ import { PlaywrightMissingError } from "../local-run.js";
|
|
|
7
7
|
import { dim, green, red, table, yellow } from "../output.js";
|
|
8
8
|
import { confirmInstall, installPlaywright } from "../playwright-install.js";
|
|
9
9
|
import { ACTION_PLAN_SCHEMA } from "../schema.generated.js";
|
|
10
|
-
import { arg, argList, flagBool, flagNum, flagStr, projectPath, readJsonFlag } from "./util.js";
|
|
10
|
+
import { arg, argList, flagBool, flagNum, flagStr, flagStrings, inGroup, projectPath, readJsonFlag, } from "./util.js";
|
|
11
11
|
const testPath = (ws, p, id) => `${projectPath(ws, p)}/tests/${id}`;
|
|
12
12
|
// A duplicate-title 409 after a green replay is idempotent when the existing row
|
|
13
13
|
// holds the same plan (a retry after a lost response) — success, not an error.
|
|
@@ -80,7 +80,7 @@ export const testCommands = [
|
|
|
80
80
|
{
|
|
81
81
|
name: "tests lint",
|
|
82
82
|
summary: "Validate a plan JSON file offline, before sending it to the server",
|
|
83
|
-
description: "Checks a plan against the published ActionPlan JSON Schema
|
|
83
|
+
description: "Checks a plan against the published ActionPlan JSON Schema: every action's required " +
|
|
84
84
|
"fields, plus the two structural rules (the first EXECUTED step must be a goto, and at " +
|
|
85
85
|
"least one step across before + steps must be an expect). Runs entirely locally, so a " +
|
|
86
86
|
"malformed plan fails here instead of costing a server round-trip. " +
|
|
@@ -106,19 +106,62 @@ export const testCommands = [
|
|
|
106
106
|
name: "tests list",
|
|
107
107
|
summary: "List the project's tests with their latest result",
|
|
108
108
|
description: "Prints a concise table by default (title / status / id / last result / last run). " +
|
|
109
|
-
"Pass --wide for every field, or --json for the raw records."
|
|
109
|
+
"Pass --wide for every field, or --json for the raw records. Returns every test " +
|
|
110
|
+
"unless --page is given; pass --page to walk a large project a slice at a time.",
|
|
110
111
|
scope: "project",
|
|
111
112
|
groupDefault: true,
|
|
112
|
-
groupSummary: "Author, inspect, version, and heal a project's tests
|
|
113
|
+
groupSummary: "Author, inspect, version, and heal a project's tests: the checks Beryl runs on each run.",
|
|
113
114
|
flags: [
|
|
114
115
|
{ name: "env", type: "string", description: "Filter by environment id" },
|
|
116
|
+
{
|
|
117
|
+
name: "group",
|
|
118
|
+
type: "string",
|
|
119
|
+
description: "Show only tests in this group (by name; see `beryl groups list`)",
|
|
120
|
+
},
|
|
115
121
|
{ name: "wide", type: "boolean", description: "Show all columns, not the concise default" },
|
|
122
|
+
{
|
|
123
|
+
name: "page",
|
|
124
|
+
type: "number",
|
|
125
|
+
description: "Return only this 1-indexed page instead of every test",
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: "page-size",
|
|
129
|
+
type: "number",
|
|
130
|
+
description: "Tests per page when --page is given (default 20, max 100)",
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: "status",
|
|
134
|
+
type: "string",
|
|
135
|
+
description: "With --page, show only this bucket: passed, failed, or blocked",
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: "ungrouped",
|
|
139
|
+
type: "boolean",
|
|
140
|
+
description: "With --page, show only tests carrying no group",
|
|
141
|
+
},
|
|
116
142
|
],
|
|
117
143
|
async run(ctx, input) {
|
|
118
144
|
const { workspaceId, projectId } = await ctx.requireProject(input);
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
145
|
+
const page = flagNum(input, "page");
|
|
146
|
+
const group = flagStr(input, "group");
|
|
147
|
+
let data;
|
|
148
|
+
if (page === undefined) {
|
|
149
|
+
data = (await ctx.client.get(`${projectPath(workspaceId, projectId)}/tests`, {
|
|
150
|
+
environment_id: flagStr(input, "env"),
|
|
151
|
+
}));
|
|
152
|
+
// GET /tests takes no group param; the paged route below filters server-side.
|
|
153
|
+
if (group)
|
|
154
|
+
data = data.filter((t) => inGroup(t, group));
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
data = (await ctx.client.get(`${projectPath(workspaceId, projectId)}/tests/page`, {
|
|
158
|
+
page,
|
|
159
|
+
page_size: flagNum(input, "page-size"),
|
|
160
|
+
status: flagStr(input, "status"),
|
|
161
|
+
group: flagBool(input, "ungrouped") ? "__ungrouped__" : group,
|
|
162
|
+
environment_id: flagStr(input, "env"),
|
|
163
|
+
})).items;
|
|
164
|
+
}
|
|
122
165
|
if (flagBool(input, "wide"))
|
|
123
166
|
return { data };
|
|
124
167
|
// `data` stays the full records so --json is unchanged; only the human table is trimmed.
|
|
@@ -129,7 +172,7 @@ export const testCommands = [
|
|
|
129
172
|
name: "tests get",
|
|
130
173
|
summary: "Show one test",
|
|
131
174
|
description: "Returns the test's metadata row (status, flags, per-environment last result), not " +
|
|
132
|
-
"the plan
|
|
175
|
+
"the plan. `tests plan` prints the stored JSON plan, `tests script` the rendered " +
|
|
133
176
|
"Playwright spec.",
|
|
134
177
|
scope: "project",
|
|
135
178
|
args: [{ name: "test-id", description: "Test id", required: true }],
|
|
@@ -141,7 +184,7 @@ export const testCommands = [
|
|
|
141
184
|
{
|
|
142
185
|
name: "tests plan",
|
|
143
186
|
summary: "Print a test's current step plan (JSON)",
|
|
144
|
-
description: "Returns the stored json_plan of the test's current version
|
|
187
|
+
description: "Returns the stored json_plan of the test's current version. `tests get` returns " +
|
|
145
188
|
"the metadata row, `tests script` the rendered Playwright spec.",
|
|
146
189
|
scope: "project",
|
|
147
190
|
args: [{ name: "test-id", description: "Test id", required: true }],
|
|
@@ -155,30 +198,30 @@ export const testCommands = [
|
|
|
155
198
|
},
|
|
156
199
|
{
|
|
157
200
|
name: "tests create",
|
|
158
|
-
summary: "Create a test case from a JSON action plan
|
|
201
|
+
summary: "Create a test case from a JSON action plan (for tests authored locally, e.g. by your coding agent)",
|
|
159
202
|
description: "The plan is a JSON object whose steps are {action, selector, url, value, ...}: the first " +
|
|
160
203
|
"EXECUTED step must be a goto, and at least one step must be an expect. Before anything is " +
|
|
161
204
|
"banked, the plan is proven by replaying it in a browser ON YOUR MACHINE with your local " +
|
|
162
|
-
"@playwright/test: the server renders the spec (`tests/compile`), the CLI runs it
|
|
205
|
+
"@playwright/test: the server renders the spec (`tests/compile`), the CLI runs it (minting " +
|
|
163
206
|
"a run inbox for await_email steps and resolving the saved login exactly as a cloud run " +
|
|
164
|
-
"would
|
|
207
|
+
"would), and only a green replay creates the test (bound to the replayed plan by its hash). " +
|
|
165
208
|
"This holds over MCP too: the replay runs on the machine hosting the MCP server, never on " +
|
|
166
209
|
"Beryl's; if @playwright/test is missing there the tool returns the install commands (on a " +
|
|
167
210
|
"terminal the CLI offers to install it). " +
|
|
168
211
|
"A red replay banks NOTHING: the failure evidence comes back (over MCP the screenshot is " +
|
|
169
212
|
"image content), you fix the plan file and re-run. The proving run is imported as the " +
|
|
170
213
|
"test's first run (--no-sync to skip). A plan that signs in with a session Beryl captured " +
|
|
171
|
-
"server-side cannot replay locally (that session never leaves Beryl's cloud)
|
|
214
|
+
"server-side cannot replay locally (that session never leaves Beryl's cloud). It falls " +
|
|
172
215
|
"back to server-side verification automatically, and says so. A session-mode plan replays locally " +
|
|
173
216
|
"fine: the server renders it with its account's stored sign-in steps in front, so " +
|
|
174
217
|
"the same identity is exercised on your machine. Optional `before` and `after` arrays hold setup and teardown " +
|
|
175
218
|
"steps: `after` runs even when a main step fails, which is how a create/update/delete test " +
|
|
176
219
|
"cleans up the record it made on the runs that go red. " +
|
|
177
|
-
"Recovery: a 409 `duplicate_title` carries existing_test_id + existing_plan_hash
|
|
220
|
+
"Recovery: a 409 `duplicate_title` carries existing_test_id + existing_plan_hash, so " +
|
|
178
221
|
"reconcile with that test (`tests get` / `tests set-plan`), don't rename-and-retry; a " +
|
|
179
222
|
"409 `plan_hash_mismatch` means the submitted plan is not the bytes that were replayed " +
|
|
180
|
-
"
|
|
181
|
-
"saturated
|
|
223
|
+
"(re-run `tests create`); a 429 with Retry-After 30 means the verify slots are " +
|
|
224
|
+
"saturated (wait and retry).",
|
|
182
225
|
scope: "project",
|
|
183
226
|
flags: [
|
|
184
227
|
{ name: "title", type: "string", required: true, description: "Title for the new test" },
|
|
@@ -186,20 +229,26 @@ export const testCommands = [
|
|
|
186
229
|
{
|
|
187
230
|
name: "description",
|
|
188
231
|
type: "string",
|
|
189
|
-
description: "
|
|
232
|
+
description: "One to three sentences stating what this test proves: the immutable outcome Beryl's healing " +
|
|
190
233
|
"checks against. State the purpose, not the steps; the one observable signal that's true " +
|
|
191
234
|
"only if the flow worked.",
|
|
192
235
|
},
|
|
193
236
|
{
|
|
194
237
|
name: "no-verify",
|
|
195
238
|
type: "boolean",
|
|
196
|
-
description: "Skip verification entirely
|
|
239
|
+
description: "Skip verification entirely: bank the authored plan as-is, unproven",
|
|
197
240
|
},
|
|
198
241
|
{
|
|
199
242
|
name: "url-override",
|
|
200
243
|
type: "string",
|
|
201
244
|
description: "Replay against this base URL instead of the environment's (e.g. http://localhost:3000). " +
|
|
202
|
-
"The banked test is then unproven against its real environment
|
|
245
|
+
"The banked test is then unproven against its real environment, and the CLI says so.",
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
name: "group",
|
|
249
|
+
type: "strings",
|
|
250
|
+
description: "Put the test in an existing project group (by name), repeatable. An unknown " +
|
|
251
|
+
"name is an error (create groups with `beryl groups create`). Omit for no group.",
|
|
203
252
|
},
|
|
204
253
|
{ name: "env", type: "string", description: "Environment id to compile and prove against" },
|
|
205
254
|
{
|
|
@@ -230,10 +279,12 @@ export const testCommands = [
|
|
|
230
279
|
const urlOverride = flagStr(input, "url-override");
|
|
231
280
|
const env = flagStr(input, "env");
|
|
232
281
|
const sync = input.flags.sync !== false;
|
|
282
|
+
const groups = flagStrings(input, "group");
|
|
233
283
|
const bank = (extra) => ctx.client.post(`${projectPath(workspaceId, projectId)}/tests`, {
|
|
234
284
|
title,
|
|
235
285
|
plan,
|
|
236
286
|
description,
|
|
287
|
+
groups,
|
|
237
288
|
...extra,
|
|
238
289
|
});
|
|
239
290
|
if (flagBool(input, "no-verify")) {
|
|
@@ -429,9 +480,9 @@ export const testCommands = [
|
|
|
429
480
|
name: "tests set-plan",
|
|
430
481
|
summary: "Replace a test's step plan from a JSON file (creates a new version)",
|
|
431
482
|
description: "Accepts the same plan shape as `tests create`, including the optional `before` and " +
|
|
432
|
-
"`after` sections
|
|
483
|
+
"`after` sections. `after` runs on pass and on fail, so cleanup happens even when the " +
|
|
433
484
|
"test goes red. Pass `--description` when the re-authored plan changes what the test " +
|
|
434
|
-
"proves; omit it to keep the test's existing intent. Saves the edit with NO replay
|
|
485
|
+
"proves; omit it to keep the test's existing intent. Saves the edit with NO replay: " +
|
|
435
486
|
"it rides into the next run unproven; `tests recompile` is the verify-first " +
|
|
436
487
|
"alternative.",
|
|
437
488
|
scope: "project",
|
|
@@ -441,7 +492,7 @@ export const testCommands = [
|
|
|
441
492
|
{
|
|
442
493
|
name: "description",
|
|
443
494
|
type: "string",
|
|
444
|
-
description: "
|
|
495
|
+
description: "One to three sentences stating what this test proves: the immutable outcome Beryl's healing " +
|
|
445
496
|
"checks against. State the purpose, not the steps; the one observable signal that's true " +
|
|
446
497
|
"only if the flow worked. Omit to keep the test's existing intent.",
|
|
447
498
|
},
|
|
@@ -472,16 +523,45 @@ export const testCommands = [
|
|
|
472
523
|
};
|
|
473
524
|
},
|
|
474
525
|
},
|
|
526
|
+
{
|
|
527
|
+
name: "tests set-groups",
|
|
528
|
+
summary: "Replace the groups a test belongs to",
|
|
529
|
+
description: "Groups are project-defined labels used to filter, run, or schedule a slice of the " +
|
|
530
|
+
"suite (`beryl runs trigger --group <name>`). This REPLACES the whole set: pass every " +
|
|
531
|
+
"group you want, or none to clear it. Names must already exist in the project " +
|
|
532
|
+
"(`beryl groups list`); an unknown name is an error, never a new group.",
|
|
533
|
+
scope: "project",
|
|
534
|
+
args: [{ name: "test-id", description: "Test id", required: true }],
|
|
535
|
+
flags: [
|
|
536
|
+
{
|
|
537
|
+
name: "group",
|
|
538
|
+
type: "strings",
|
|
539
|
+
description: "Group name, repeatable. Omit entirely to clear the set.",
|
|
540
|
+
},
|
|
541
|
+
],
|
|
542
|
+
examples: [
|
|
543
|
+
"beryl tests set-groups 4f… --group Checkout --group Smoke",
|
|
544
|
+
"beryl tests set-groups 4f…",
|
|
545
|
+
],
|
|
546
|
+
async run(ctx, input) {
|
|
547
|
+
const { workspaceId, projectId } = await ctx.requireProject(input);
|
|
548
|
+
return {
|
|
549
|
+
data: await ctx.client.patch(testPath(workspaceId, projectId, arg(input, "test-id")), {
|
|
550
|
+
groups: flagStrings(input, "group") ?? [],
|
|
551
|
+
}),
|
|
552
|
+
};
|
|
553
|
+
},
|
|
554
|
+
},
|
|
475
555
|
{
|
|
476
556
|
name: "tests quarantine",
|
|
477
557
|
summary: "Mute a flaky test: it keeps running, but its failures stop failing the run",
|
|
478
|
-
description: "A quarantined test still executes and its result is still recorded and visible
|
|
558
|
+
description: "A quarantined test still executes and its result is still recorded and visible. Its " +
|
|
479
559
|
"red lands in the run's quarantined_count and gates neither the run's verdict nor exit " +
|
|
480
560
|
"codes, so it can't red-light a deploy. Use " +
|
|
481
561
|
"it on a persistently flaky test instead of deleting it (which destroys the history) or " +
|
|
482
562
|
"asking support to deactivate it (which stops it running at all). After 5 consecutive " +
|
|
483
|
-
"clean passes the test reports rehab_ready
|
|
484
|
-
"itself. `off` un-quarantines.",
|
|
563
|
+
"clean passes the test reports rehab_ready (advisory only, nothing un-quarantines " +
|
|
564
|
+
"itself). `off` un-quarantines.",
|
|
485
565
|
scope: "project",
|
|
486
566
|
args: [
|
|
487
567
|
{ name: "test-id", description: "Test id", required: true },
|
|
@@ -518,11 +598,11 @@ export const testCommands = [
|
|
|
518
598
|
summary: "Validate + verify an edited plan against the live site before persisting",
|
|
519
599
|
description: "Unlike `tests set-plan` (which saves the edit and lets it ride into the next run), " +
|
|
520
600
|
"this replays the edited plan against the live site before anything persists. A " +
|
|
521
|
-
"deterministic replay failure (verdict `drop`) REJECTS the edit
|
|
522
|
-
"the prior plan stays live
|
|
601
|
+
"deterministic replay failure (verdict `drop`) REJECTS the edit (persisted:false, " +
|
|
602
|
+
"the prior plan stays live) and returns the failure evidence (over MCP the " +
|
|
523
603
|
"screenshot is image content). Verdict `flag` (the runner errored, no verdict on " +
|
|
524
604
|
"the flow) persists the plan but reports it unverified. Returns 429 with " +
|
|
525
|
-
"Retry-After 30 when the 2 inline-verify slots are saturated
|
|
605
|
+
"Retry-After 30 when the 2 inline-verify slots are saturated (wait and retry).",
|
|
526
606
|
scope: "project",
|
|
527
607
|
args: [{ name: "test-id", description: "Test id", required: true }],
|
|
528
608
|
flags: [
|
|
@@ -591,7 +671,7 @@ export const testCommands = [
|
|
|
591
671
|
{
|
|
592
672
|
name: "tests restore",
|
|
593
673
|
summary: "Restore a test to an earlier version",
|
|
594
|
-
description: "Copies the named older version's plan forward as a NEW head version
|
|
674
|
+
description: "Copies the named older version's plan forward as a NEW head version, unlike " +
|
|
595
675
|
"`tests reset`, which flips authored_by back to `system` and leaves the plan " +
|
|
596
676
|
"untouched.",
|
|
597
677
|
scope: "project",
|
|
@@ -610,7 +690,7 @@ export const testCommands = [
|
|
|
610
690
|
name: "tests reset",
|
|
611
691
|
summary: "Discard user edits and return the test to its latest system-authored version",
|
|
612
692
|
description: "Flips authored_by back to `system` WITHOUT changing the plan (the next " +
|
|
613
|
-
"regeneration overwrites it)
|
|
693
|
+
"regeneration overwrites it), unlike `tests restore`, which copies an older " +
|
|
614
694
|
"version's plan forward as a new version.",
|
|
615
695
|
scope: "project",
|
|
616
696
|
args: [{ name: "test-id", description: "Test id", required: true }],
|
|
@@ -659,9 +739,9 @@ export const testCommands = [
|
|
|
659
739
|
name: "tests script",
|
|
660
740
|
summary: "Print the rendered Playwright spec for a test (or an unbanked plan file)",
|
|
661
741
|
description: "With a test id, fetches the banked test's rendered .spec.ts. With --file, compiles a " +
|
|
662
|
-
"plan JSON that has NOT been banked yet
|
|
742
|
+
"plan JSON that has NOT been banked yet (the same render `tests create` proves locally) " +
|
|
663
743
|
"so you can inspect exactly what would run before creating anything. This returns the " +
|
|
664
|
-
"executable spec
|
|
744
|
+
"executable spec. `tests plan` returns the stored JSON plan it is rendered from, " +
|
|
665
745
|
"`tests get` the metadata row.",
|
|
666
746
|
scope: "project",
|
|
667
747
|
args: [{ name: "test-id", description: "Test id (omit when passing --file)" }],
|
package/dist/commands/util.js
CHANGED
|
@@ -54,3 +54,23 @@ export function readJsonFlag(input, name) {
|
|
|
54
54
|
throw new UsageError(`--${name}: ${file} is not valid JSON (${err.message})`);
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
+
export function flagStrings(input, name) {
|
|
58
|
+
const v = input.flags[name];
|
|
59
|
+
return v && v.length > 0 ? v : undefined;
|
|
60
|
+
}
|
|
61
|
+
export function inGroup(row, group) {
|
|
62
|
+
const want = group.trim().toLowerCase();
|
|
63
|
+
return (row.groups ?? []).some((g) => g.toLowerCase() === want);
|
|
64
|
+
}
|
|
65
|
+
/** Resolve a --group name to the ids of the project's ACTIVE tests in it.
|
|
66
|
+
* Client-side on purpose: the run endpoint keeps one selection mechanism
|
|
67
|
+
* (test_case_ids), so a run always records the exact ids it ran even if group
|
|
68
|
+
* membership changes later. */
|
|
69
|
+
export function idsInGroup(rows, group) {
|
|
70
|
+
return rows.filter((t) => t.is_active !== false && inGroup(t, group)).map((t) => t.id);
|
|
71
|
+
}
|
|
72
|
+
/** Match a `--group` value against the project's groups by name (case-insensitive) or id. */
|
|
73
|
+
export function findGroup(groups, ref) {
|
|
74
|
+
const want = ref.trim().toLowerCase();
|
|
75
|
+
return groups.find((g) => g.id === ref || g.name.toLowerCase() === want);
|
|
76
|
+
}
|
package/dist/commands/watch.js
CHANGED
|
@@ -68,7 +68,8 @@ export async function watchRun(ctx, ws, project, runId, timeoutMinutes) {
|
|
|
68
68
|
// is reported too, so a suite that only stays green by retrying can't hide it.
|
|
69
69
|
const extra = (counters.cancelled ? yellow(`, ${counters.cancelled} cancelled`) : "") +
|
|
70
70
|
(counters.quarantined ? yellow(`, ${counters.quarantined} quarantined`) : "") +
|
|
71
|
-
(counters.flaky ? yellow(`, ${counters.flaky} flaky`) : "")
|
|
71
|
+
(counters.flaky ? yellow(`, ${counters.flaky} flaky`) : "") +
|
|
72
|
+
(counters.healed ? yellow(`, ${counters.healed} healed`) : "");
|
|
72
73
|
const summary = failed > 0
|
|
73
74
|
? red(`${failed} failed`) + `, ${passed} passed` + extra
|
|
74
75
|
: green(`${passed} passed`) + extra;
|
package/dist/registry/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { authCommands } from "../commands/auth.js";
|
|
|
4
4
|
import { configCommands } from "../commands/config-vars.js";
|
|
5
5
|
import { environmentCommands } from "../commands/environments.js";
|
|
6
6
|
import { explorationCommands } from "../commands/explorations.js";
|
|
7
|
+
import { groupCommands } from "../commands/groups.js";
|
|
7
8
|
import { healthCommands } from "../commands/health.js";
|
|
8
9
|
import { mailboxCommands } from "../commands/mailboxes.js";
|
|
9
10
|
import { initCommands } from "../commands/init.js";
|
|
@@ -57,6 +58,7 @@ export const commands = [
|
|
|
57
58
|
...projectCommands,
|
|
58
59
|
...environmentCommands,
|
|
59
60
|
...testCommands,
|
|
61
|
+
...groupCommands,
|
|
60
62
|
...runCommands,
|
|
61
63
|
...healthCommands,
|
|
62
64
|
...explorationCommands,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beryl-so/cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Beryl on the command line
|
|
3
|
+
"version": "0.33.0",
|
|
4
|
+
"description": "Beryl on the command line \u2014 projects, runs, the exploring agent, and an MCP server over the same commands.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"homepage": "https://beryl.so/docs/cli",
|