@getmagical/cli 0.4.0 → 0.7.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,15 +12,376 @@ Magical CLI for the shared MCP operation surface.
12
12
  ```bash
13
13
  mgcl --version
14
14
  mgcl update
15
+ mgcl settings env --env uk
15
16
  mgcl auth login
16
- mgcl settings env base-url http://main.localhost:1355
17
17
  mgcl org list
18
18
  mgcl automations list --limit 10
19
19
  mgcl automations update --id ... --input-json ...
20
20
  mgcl automation-runs list --automation-id ...
21
21
  mgcl automations run-draft --draft-automation-id ... --agent-id ... --idempotency-key ... --config-json '{"startInTakeOverMode":true,"captureActions":true,"approvalMode":"HUMAN_APPROVAL","consistencyCheckCount":3}'
22
+ mgcl automations publish --draft-automation-id ... # non-production only: mgcl refuses against the production API, and the API rejects it too
22
23
  ```
23
24
 
25
+ ## Deployment targets
26
+
27
+ Use the global `--env us|uk|stg` option to select a complete Magical API and
28
+ WorkOS authentication target for one command:
29
+
30
+ ```bash
31
+ mgcl --env us org list
32
+ mgcl --env uk auth login
33
+ mgcl --env uk automations list --json
34
+ mgcl --env stg org list
35
+ ```
36
+
37
+ The built-in presets contain only public deployment configuration:
38
+
39
+ | Preset | Platform | Magical API | WorkOS client |
40
+ | --- | --- | --- | --- |
41
+ | `us` | `https://platform.getmagical.io` | `https://api-agt.getmagical.io` | `client_01JJZ6XJ1RF248P20WF63M4VAM` |
42
+ | `uk` | `https://platform.uk.getmagical.io` | `https://api-agt.uk.getmagical.io` | `client_01M0J897D67RXRB4VBNTXBF9ST` |
43
+ | `stg` | `https://platform-staging.getmagical.net` | `https://api-agt-staging.getmagical.net` | `client_01JJZ6X26BGFBT8AC303XPQ9EQ` |
44
+
45
+ All three use the public WorkOS API at `https://api.workos.com`. A platform
46
+ domain in a built-in preset resolves to its corresponding Magical API origin
47
+ before requests are sent.
48
+
49
+ For an explicit target, combine `--domain` with `--workosEnv`. `--workosEnv`
50
+ accepts the `us`, `uk`, or `stg` WorkOS configuration alias, or a public WorkOS
51
+ client ID beginning with `client_`. It never accepts or requires a WorkOS API
52
+ key.
53
+
54
+ ```bash
55
+ mgcl \
56
+ --domain https://platform.uk.getmagical.io \
57
+ --workosEnv uk \
58
+ auth login
59
+
60
+ mgcl \
61
+ --domain https://api.example.internal \
62
+ --workosEnv client_01ABCDEF123456789 \
63
+ org list
64
+ ```
65
+
66
+ An unknown custom domain needs a deliberately selected WorkOS environment,
67
+ either from saved settings or the same command. A domain-only override keeps a
68
+ saved explicit `--env` or `--workosEnv` selection, but it never inherits the
69
+ implicit built-in US default or infers staging from the presence of a custom
70
+ URL.
71
+
72
+ ### Save a default target
73
+
74
+ Persist the same selectors with `mgcl settings env`, inspect the saved and
75
+ effective target with no options, or reset to the built-in US default:
76
+
77
+ ```bash
78
+ mgcl settings env --env uk
79
+ mgcl settings env
80
+ mgcl auth login
81
+
82
+ mgcl settings env \
83
+ --domain https://platform.uk.getmagical.io \
84
+ --workosEnv uk
85
+
86
+ mgcl settings env --reset
87
+ ```
88
+
89
+ A global selector applies only to its invocation and never rewrites saved
90
+ settings. An explicit global `--env` starts from that complete preset rather
91
+ than inheriting saved overrides; global `--domain` and `--workosEnv` then
92
+ override the selected target for that command.
93
+
94
+ Saved interactive sessions are bound to the resolved API and WorkOS target.
95
+ When the selected target does not match that saved session, mgcl requires
96
+ authentication for the selected target instead of silently reusing it.
97
+ Changing saved settings clears incompatible saved authentication; saving the
98
+ same effective target preserves it. Explicit and environment-provided API keys
99
+ remain invocation credentials and are validated by the selected deployment.
100
+
101
+ The legacy `mgcl settings env base-url <url>` command and saved `env.baseUrl`
102
+ values remain supported for recognized preset URLs. A legacy unknown URL with
103
+ no deliberately saved WorkOS selection cannot identify its authentication
104
+ environment safely and must be migrated explicitly.
105
+ For local or preview services that authenticate against staging WorkOS, use:
106
+
107
+ ```bash
108
+ mgcl settings env \
109
+ --domain http://main.localhost:1355 \
110
+ --workosEnv stg
111
+ mgcl auth login
112
+ ```
113
+
114
+ This native configuration replaces the temporary workaround of patching an
115
+ installed mgcl package to select the UK WorkOS client.
116
+
117
+ ## Run evidence and private files
118
+
119
+ Discover immutable S3 references before downloading a specific file:
120
+
121
+ ```bash
122
+ mgcl automation-runs files --id <automation-run-id> --org <org> --json
123
+ mgcl files get --key <s3-key> --download ./local-file --org <org> --json
124
+ ```
125
+
126
+ `automation-runs files` scans run input, agent input, and paged tool-call and
127
+ tool-result memories. Its JSON output identifies each file's agent run,
128
+ iteration, field path, role, source, tool call, and tool name, plus whether the
129
+ scan was truncated. `files get` downloads into the current directory using the
130
+ original file name when `--download` is omitted. It refuses to replace an
131
+ existing destination unless `--force` is present.
132
+
133
+ Use the dedicated commands for final agent output and database-backed tool
134
+ result media:
135
+
136
+ ```bash
137
+ mgcl agent-runs output --id <agent-run-id> --org <org> --json
138
+ mgcl automation-runs iteration-media \
139
+ --iteration-id <iteration-id> \
140
+ --media-id <media-id> \
141
+ --download ./tool-result-media \
142
+ --org <org> \
143
+ --json
144
+ ```
145
+
146
+ Private download URLs are transport details. The CLI writes file bytes only to
147
+ the requested local path and omits signed or authenticated URLs from both human
148
+ and JSON output. These read paths require `runs:read` when an API key is used.
149
+
150
+ Knowledge Base and Memory discovery stays metadata-only. Retrieve a selected
151
+ immutable version, or upload an ordinary replay input, through mgcl's private
152
+ file transport:
153
+
154
+ ```bash
155
+ mgcl knowledge read --key <repository-file-key> --download ./knowledge-file
156
+ mgcl memories read --key <repository-file-key> --download ./memory-file
157
+ mgcl files upload --path ./run-input.pdf
158
+ ```
159
+
160
+ `files get`, `automation-runs iteration-media`, and these three transfer
161
+ commands are mgcl-only. They are omitted from the generated raw MCP tool list
162
+ so signed download and upload URLs never become normal MCP output. The GraphQL
163
+ operations remain available to mgcl's private transport.
164
+
165
+ For verification, download evidence into a private session-specific temporary
166
+ directory. Do not echo or paste raw file contents or download URLs into the
167
+ transcript, and remove the files during session cleanup. If a file is missing,
168
+ record that evidence as unverifiable instead of inferring its contents.
169
+
170
+ Inspect a retained network recording by its authoritative automation run ID:
171
+
172
+ ```bash
173
+ mgcl network-recordings get --automation-run-id <run-id> --org <org> --json
174
+ mgcl network-recordings get --automation-run-id <run-id> --output ./recording.mitm --org <org> --json
175
+ mgcl network-recordings exchanges --automation-run-id <run-id> --limit 100 --org <org> --json
176
+ mgcl network-recordings response --automation-run-id <run-id> --exchange <exchange-ref> --output ./response.pdf --org <org> --json
177
+ ```
178
+
179
+ `get` is metadata-only unless `--output` intentionally requests the complete
180
+ archive. `exchanges` and `response` privately download a fresh archive for that
181
+ invocation and remove it after local parsing. This keeps the organization, run,
182
+ and recording association authoritative without accepting archive imports.
183
+ Downloads are capped at 256 MiB, require the received byte count to match the
184
+ availability metadata, use private file permissions, and refuse an existing
185
+ destination. Metadata lookup has a 30-second deadline. Complete archive
186
+ transfer, including response-body streaming, has a separate 120-second
187
+ deadline.
188
+
189
+ Local inspection uses mitmproxy's supported archive reader and requires Python
190
+ 3.12 or newer with exactly `mitmproxy==12.2.3`. mgcl does not install this
191
+ optional runtime. Create a dedicated environment and point mgcl at its Python
192
+ executable:
193
+
194
+ ```bash
195
+ python3 -m venv ~/.local/share/mgcl/mitmproxy-12.2.3
196
+ ~/.local/share/mgcl/mitmproxy-12.2.3/bin/python -m pip install 'mitmproxy==12.2.3'
197
+ export MGCL_MITMPROXY_PYTHON=~/.local/share/mgcl/mitmproxy-12.2.3/bin/python
198
+ ```
199
+
200
+ Exchange output includes a recording-specific stable reference, flow ordinal,
201
+ method, request origin, response status, normalized content media type,
202
+ and body availability. Request paths, query strings, user info, headers, and
203
+ bodies are omitted. The scan reports separate result and 20,000-flow limits,
204
+ counts, and whether it was complete. Response extraction verifies the exchange
205
+ reference against the freshly downloaded archive and reports the decoded entity
206
+ body's size and SHA-256 provenance without printing its contents.
207
+
208
+ Inspection has a 60-second processing deadline and rejects an archive over 256
209
+ MiB or an individual serialized flow over 32 MiB. Extraction additionally
210
+ rejects encoded bodies over 32 MiB, decoded bodies over 64 MiB, or decompression
211
+ over 100 times the encoded size. Version 1 extraction supports an absent or
212
+ `identity` content encoding, `gzip`, and `deflate`. Brotli (`br`), Zstandard
213
+ (`zstd`), unknown, and stacked encodings return `UNSUPPORTED_ENCODING` without
214
+ creating an output file. Truncated, trailing, or concatenated gzip and deflate
215
+ streams are invalid. A missing response or body, an unsupported encoding, a
216
+ malformed archive, or any exceeded bound means the requested evidence cannot be
217
+ verified; it does not establish that the recorded automation failed.
218
+
219
+ ## Cloud authentication
220
+
221
+ Use a WorkOS user API key for unattended workloads. Create keys from a trusted
222
+ laptop with a saved interactive login; do not run the setup wizard in the
223
+ cloud workload itself:
224
+
225
+ ```bash
226
+ mgcl auth login
227
+ mgcl auth setup-cloud --output ./magical-cloud.env
228
+ ```
229
+
230
+ The wizard refreshes the interactive session, discovers active organization
231
+ memberships, and lets you select one or more organizations, a purpose, an
232
+ `inspect`, `build`, or `operate` preset, all available permissions, or exact
233
+ scopes, an optional expiry, and one default organization. Interactive sessions
234
+ use arrow-key and checkbox prompts. The wizard displays the owner,
235
+ organizations, grants, expiry, and destination for confirmation before creating
236
+ anything. Keys do not expire by default; choose an expiry when the workload has
237
+ a known lifetime.
238
+
239
+ For non-interactive setup, pass `--permissions all` to expand to every
240
+ permission supported by that CLI version. `all` is a CLI shortcut and is never
241
+ sent to WorkOS as a permission.
242
+
243
+ The output is a sourceable environment file. Copy its values into the cloud
244
+ provider's secret store rather than committing the file. Each selected
245
+ organization gets one key and an organization-specific variable:
246
+
247
+ ```bash
248
+ MAGICAL_API_KEY_ORG_01JTH6STB70QTCXJWVJE22G9J3=...
249
+ ```
250
+
251
+ The suffix is the uppercase ULID from the canonical organization ID, without
252
+ the `org_` prefix. The selected default organization's same key is also written
253
+ as `MAGICAL_API_KEY`; this alias does not create another key.
254
+
255
+ For a one-command override, pass the global `--api-key <key>` option before or
256
+ after the command path:
257
+
258
+ ```bash
259
+ mgcl automations list --api-key "$ONE_TIME_MAGICAL_API_KEY"
260
+ ```
261
+
262
+ The key is ephemeral: it is not written to CLI state, preferences, the
263
+ keychain, or the environment (`org use` may still save the non-secret
264
+ organization choice). It is the only credential candidate for that invocation,
265
+ so the CLI ignores all `MAGICAL_API_KEY` variables and saved login credentials
266
+ rather than falling back after a failure. With `--org`, the key must belong to
267
+ that exact organization. Literal command-line values can be visible in shell
268
+ history and process listings, so prefer expansion from a secret manager or
269
+ environment variable and continue using the canonical environment variables
270
+ for unattended workloads.
271
+
272
+ ### Organization selection
273
+
274
+ When any `MAGICAL_API_KEY` variable is configured, workspace commands use API
275
+ key mode and never fall back to a saved login or direct access token. Selection
276
+ is deterministic:
277
+
278
+ 1. An explicit `--org <organization>`.
279
+ 2. The organization saved for the current API origin by `mgcl org use`.
280
+ 3. The organization validated from `MAGICAL_API_KEY`.
281
+ 4. The only valid `MAGICAL_API_KEY_ORG_*` key, when exactly one is available.
282
+
283
+ For a selected organization, its exact organization-specific variable wins.
284
+ If that variable exists but is invalid, expired, or insufficient, the command
285
+ fails instead of trying `MAGICAL_API_KEY` or another identity. When it is
286
+ absent, `MAGICAL_API_KEY` is eligible only if its metadata identifies that same
287
+ organization. The CLI validates identity and necessary permissions before the
288
+ business request and never retries that request under another key. Organization
289
+ discovery also rejects configured keys owned by different users.
290
+
291
+ Use live, sanitized metadata to inspect or choose an organization:
292
+
293
+ ```bash
294
+ mgcl org list
295
+ mgcl org use <org-id-or-exact-name>
296
+ mgcl auth status
297
+ ```
298
+
299
+ The saved choice contains no credential and is isolated by API origin.
300
+ `auth status` reports the active authentication source plus key and organization
301
+ metadata, never the raw key. `mgcl auth logout` clears saved interactive auth
302
+ and a direct access token, but it cannot unset environment variables or revoke
303
+ their keys; configured environment keys remain active.
304
+
305
+ ### Manage, rotate, and recover keys
306
+
307
+ Key management always requires and refreshes the saved interactive session. It
308
+ deliberately ignores environment API keys and direct access tokens, and rejects
309
+ `--api-key` so a management action cannot silently run under another identity:
310
+
311
+ ```bash
312
+ mgcl auth keys list --org <org>
313
+ mgcl auth keys revoke <key-id> --org <org>
314
+ ```
315
+
316
+ Listing returns sanitized metadata, including grants, expiry, last use, and an
317
+ obfuscated value. WorkOS returns a raw value only once, during creation. If the
318
+ export is lost, it cannot be recovered: revoke that key and create a
319
+ replacement. To rotate safely, create and install the replacement, verify the
320
+ workload with it, and then revoke the old key. Start a rotation with a new
321
+ output path (and therefore a new default checkpoint) so the completed original
322
+ setup remains an audit and recovery record:
323
+
324
+ ```bash
325
+ mgcl auth setup-cloud --output ./magical-cloud-rotation-2026-09.env
326
+ ```
327
+
328
+ Rerunning a completed setup checkpoint is intentionally a no-op, and `--force`
329
+ cannot restart or change that saved plan. Use a new `--output`, or both a new
330
+ `--output` and `--checkpoint`, for every rotation.
331
+
332
+ Setup writes every returned secret immediately and durably, and never prints
333
+ one to the terminal. Its output and sidecar checkpoint are owner-only files
334
+ (`0600`); the checkpoint contains recovery metadata but no raw key. Keep both
335
+ private, and rerun the same setup command after an interruption so it can use
336
+ the checkpoint and idempotency records to resume or reconcile an uncertain
337
+ attempt without blindly creating duplicates. Existing output is not replaced
338
+ without explicit overwrite confirmation.
339
+
340
+ Keys belong to the API environment where they were created. Configure a custom
341
+ origin before login and setup, and use separate output and secret records for
342
+ local, staging, preview, and production environments:
343
+
344
+ ```bash
345
+ mgcl settings env base-url https://api.example.internal
346
+ mgcl auth login
347
+ mgcl auth setup-cloud --output ./example-cloud.env
348
+ ```
349
+
350
+ Changing or resetting the base URL clears saved interactive auth. API requests
351
+ also reject redirects instead of forwarding a bearer credential to another
352
+ origin.
353
+
354
+ Cloud keys are least-privilege automation credentials. Their effective access
355
+ is the intersection of the key's scopes and the owner's current WorkOS role;
356
+ an active membership is required on every request. Unsupported surfaces remain
357
+ denied, including eval management, publishing and deletion, schedules, admin
358
+ operations, raw credential values, browser sessions, interactive sessions, and
359
+ key minting.
360
+
361
+ ### Operator rollout and rollback
362
+
363
+ Deploy the backend before releasing the CLI flow. In WorkOS, create these
364
+ permissions and grant the appropriate subset to member roles:
365
+
366
+ ```text
367
+ automations:read automations:write runs:read runs:execute runs:control
368
+ store:read store:write skills:read skills:write credentials:read
369
+ captures:read captures:write regressions:read regressions:run
370
+ knowledge:read memory:read files:write
371
+ ```
372
+
373
+ The Knowledge Base, Memory, and replay-upload commands remain pending until the
374
+ backend API is deployed and these three permission slugs are configured on the
375
+ intended WorkOS roles.
376
+
377
+ Roles that manage their own keys also need WorkOS's
378
+ `widgets:user-api-keys:manage-self` permission. Then deploy and verify the
379
+ backend before releasing the cloud-auth CLI. The backend defaults
380
+ `WORKOS_USER_API_KEYS_ENABLED` to `true`; setting it to `false` is the emergency
381
+ rollback. While disabled, the backend rejects API-key authentication and new
382
+ cloud setup, while interactive login and interactive key listing/revoking
383
+ remain available so existing WorkOS records can be managed manually.
384
+
24
385
  ## Registered Evals
25
386
 
26
387
  Registered evals and their persisted runs are global resources, so these
@@ -114,18 +475,26 @@ MCP server. MCP callers must provide `idempotencyKey` and
114
475
  current branch. Omit it to target main; branch-aware responses include
115
476
  `branchId: null` and the selected main `headVersionId`.
116
477
 
117
- This release adds exactly five commands: branch list, create, get, and merge,
118
- plus workbench patch readiness.
478
+ Branch commands: list, create, get, merge-preview, discard-changes, and
479
+ merge, plus
480
+ workbench patch readiness.
119
481
 
120
482
  ```bash
121
483
  mgcl automations branches list --automation-id <automation-id> --json
122
484
  mgcl automations branches create --automation-id <automation-id> --name experiment --json
123
485
  mgcl --branch-id <branch-id> automations branches get --automation-id <automation-id> --json
124
486
  mgcl --branch-id <branch-id> automations update --id <automation-id> --input-json '{"baseVersionId":"<head-version-id>","name":"Experiment"}' --json
487
+ mgcl --branch-id <branch-id> automations branches merge-preview --automation-id <automation-id> --json
488
+ mgcl --branch-id <branch-id> automations branches discard-changes --automation-id <automation-id> --change-ids agent:update:<agent-id>:instructions --source-version-id <source-version-id> --target-version-id <target-version-id> --json
125
489
  mgcl --branch-id <branch-id> automations branches merge --automation-id <automation-id> --json
126
490
  mgcl --branch-id <branch-id> workbench patch readiness --target-draft-automation-id <automation-id> --operations-json '[{"setAutomationName":{"name":"Experiment readiness preview"}}]' --json
127
491
  ```
128
492
 
493
+ Merge previews report agent edits per field, and settings per config key:
494
+ `agent:update:<agent-id>:config.model`, `config.tools`, `config.plugins.memory`,
495
+ or `config.devOnly` for the developer-only keys, with the key in `configKey`.
496
+ Automation settings follow the same shape (`automation:config.systemPrompt`).
497
+
129
498
  Branch creation defaults to main. Use `--source-branch-id` and optionally
130
499
  `--source-version-id` to fork from another branch or an older version in that
131
500
  branch's history. Names must use lowercase letters or numbers separated by
@@ -135,7 +504,24 @@ leading or trailing dashes, repeated dashes, and over-length names are
135
504
  rejected before an API request. Branch IDs, not names, identify targets, and
136
505
  every automation or branch ID must be a UUID; malformed IDs are rejected
137
506
  before an API request.
138
- Merge previews the same change set as the web UI. A conflict returns
507
+ `merge-preview` explains the merge without writing anything. Each change carries a
508
+ stable `id`, a `kind`, and for agent edits the `agentId` and `field`
509
+ (`name`, `description`, `instructions`, `inputSchema`, `outputSchema`,
510
+ `config`, `agentLibraryEntity`, `type`), so a field main also changed
511
+ conflicts on its own while the agent's other fields stay mergeable.
512
+ Connections are keyed by `fromAgentId`/`toAgentId`, agent positions are one
513
+ grouped `layout:agents` change that never conflicts, and a connection to an
514
+ agent main deleted is a conflict. `conflictDescription` says why a change
515
+ conflicts; `discardable` marks changes that can be reverted.
516
+
517
+ `discard-changes` is the only conflict resolution: it reverts the named changes on
518
+ the branch as a new branch version so main keeps its values, and returns the
519
+ new head plus the refreshed preview. Pass `--source-version-id` and
520
+ `--target-version-id` from the preview you acted on; the command is rejected
521
+ when either head moved since. Discarding an added or removed agent also
522
+ reverts its added or removed connections.
523
+
524
+ `merge` previews the same change set as the web UI. A conflict returns
139
525
  `status: "conflict"`, does not change main or delete the branch, and exits
140
526
  nonzero so scripts gating on the exit code never mistake it for an applied
141
527
  merge. A conflict-free merge returns `status: "merged"`, the saved-main
@@ -145,7 +531,8 @@ are intentionally deferred.
145
531
  The global branch target is accepted by `automations update`, `automations
146
532
  run-draft`, `automations diff-from-published`, `workbench diagnostics`,
147
533
  `workbench schema-suggestions`, and `workbench patch preview`, `readiness`,
148
- and `apply`. It is required by `automations branches get` and `merge`. Other
534
+ and `apply`. It is required by `automations branches get`, `merge-preview`,
535
+ `discard-changes`, and `merge`. Other
149
536
  commands reject `--branch-id` before making an API request, and
150
537
  `mgcl --help` lists the branch-aware commands. Branch-aware responses identify the selected
151
538
  target with `branchId` and `headVersionId`. Merge returns `branchId`, its exact
@@ -209,23 +596,20 @@ Run the CLI from source without building:
209
596
  npm run cli -- --help
210
597
  ```
211
598
 
212
- Production installs use the bundled WorkOS client ID by default. To persist a
213
- local or staging API target, set:
599
+ Use an isolated configuration directory when testing a local or preview target
600
+ without changing the normal CLI profile:
214
601
 
215
602
  ```bash
216
- mgcl settings env base-url http://main.localhost:1355
603
+ export MAGICAL_CLI_CONFIG_DIR="$(mktemp -d)"
604
+ export MAGICAL_CLI_REFRESH_TOKEN_STORE=file
605
+ mgcl settings env --domain http://main.localhost:1355 --workosEnv stg
217
606
  mgcl auth login
218
607
  ```
219
608
 
220
- When a persisted base URL override is present, `mgcl auth login` uses the
221
- bundled staging/dev WorkOS client ID automatically. Changing or resetting the
222
- override clears saved auth so you can log into the correct environment again.
223
-
224
- To remove the override and return to defaults:
225
-
226
- ```bash
227
- mgcl settings env base-url --reset
228
- ```
609
+ Complete the browser flow only when that isolated profile is ready for use,
610
+ then run `mgcl org list` and one read-only command against the same target.
611
+ Move the temporary directory to Trash after the test credentials are no longer
612
+ needed: `trash "$MAGICAL_CLI_CONFIG_DIR"`.
229
613
 
230
614
  ## Install Script
231
615
 
@@ -249,6 +633,13 @@ Once installed, users can update from the same channel with:
249
633
  mgcl --update
250
634
  ```
251
635
 
636
+ The service checks the npm `latest` version dynamically for mgcl requests, so
637
+ an older version observed during a rollout is not a permanent minimum. Release
638
+ new CLI behavior by merging it with its package-version bump, deploying any
639
+ required server support first, then creating the matching `cli-v<version>`
640
+ GitHub release and verifying that npm `latest` and each target deployment accept
641
+ the published version.
642
+
252
643
  To remove the managed install:
253
644
 
254
645
  ```bash