@apicircle/cli 1.0.1 → 1.0.2

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/LICENSE CHANGED
@@ -1,110 +1,110 @@
1
- API Circle Studio License
2
- Custom Source-Available License, v1.0
3
-
4
- Copyright (c) 2026 Deva Prakash ("Licensor")
5
-
6
- The source code in this repository ("the Software") is made available for
7
- the purposes of transparency, security review, contribution, and personal
8
- evaluation. This is NOT an open-source license as defined by the Open
9
- Source Initiative.
10
-
11
- 0. Definitions
12
-
13
- "Commercial Use" means any use of the Software that is intended for
14
- or directed toward commercial advantage or monetary compensation,
15
- whether direct or indirect, including without limitation:
16
-
17
- (a) using the Software to build, test, develop, deploy, or operate
18
- any product, service, application, or system that is sold,
19
- licensed, hosted, distributed, or otherwise made available to
20
- any third party for a fee or other consideration;
21
- (b) using the Software in the course of paid employment, paid
22
- consulting, paid contracting, freelance work, or any other
23
- revenue-generating activity, regardless of whether the Software
24
- itself is sold or transferred;
25
- (c) using the Software internally within a for-profit organization
26
- beyond the Evaluation Period defined below;
27
- (d) integrating the Software, or any portion of it, into any tool,
28
- pipeline, automation, or workflow that supports the commercial
29
- operations of any business;
30
- (e) using the Software to provide a hosted, managed, or embedded
31
- service of any kind to a third party, whether free or paid.
32
-
33
- "Non-Commercial Use" means any use that is not Commercial Use,
34
- including personal hobby projects, individual learning, academic
35
- research, classroom instruction, and good-faith contribution to
36
- this repository.
37
-
38
- "Evaluation Period" means a single, continuous period of up to
39
- thirty (30) days during which a for-profit organization may
40
- internally evaluate the Software at no charge. After the Evaluation
41
- Period expires, any further use of the Software by that organization
42
- constitutes Commercial Use and requires a separate commercial
43
- license from the Licensor.
44
-
45
- 1. Permitted Use
46
-
47
- You may, without charge:
48
-
49
- (a) view, read, and study the source code of the Software;
50
- (b) run the Software, in source or compiled form, for your own
51
- Non-Commercial Use, or for Commercial Use solely within the
52
- Evaluation Period;
53
- (c) submit improvements to the Software back to this repository via
54
- pull request, subject to Section 3 (Contributions).
55
-
56
- 2. Prohibited Use
57
-
58
- Without prior written permission from the Licensor, you may NOT:
59
-
60
- (a) make any Commercial Use of the Software, in whole or in part,
61
- except during the Evaluation Period as defined in Section 0;
62
- (b) redistribute the Software, in source or compiled form, whether
63
- modified or unmodified, to any third party;
64
- (c) sublicense, sell, rent, lease, or otherwise transfer the
65
- Software or any rights granted herein;
66
- (d) remove, obscure, or alter any copyright, trademark, attribution,
67
- or license notice contained in the Software;
68
- (e) use the names "API Circle", "API Circle Studio", or any related
69
- logos or trademarks, except as required for accurate attribution.
70
-
71
- 3. Contributions
72
-
73
- By submitting any contribution (including but not limited to code,
74
- documentation, or assets) to this repository, you grant the Licensor
75
- a perpetual, worldwide, irrevocable, royalty-free, sublicensable
76
- license to use, modify, distribute, and relicense your contribution
77
- under any terms, including the terms of this license or any future
78
- version thereof.
79
-
80
- 4. No Trademark License
81
-
82
- This license does not grant permission to use the trade names,
83
- trademarks, service marks, or product names of the Licensor, except
84
- as required for reasonable and customary use in describing the
85
- origin of the Software.
86
-
87
- 5. Termination
88
-
89
- The rights granted in Section 1 terminate automatically if you
90
- breach any term of this license. Upon termination, you must cease
91
- all use of the Software and destroy all copies in your possession.
92
-
93
- 6. Disclaimer of Warranty
94
-
95
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
96
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
97
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
98
- NON-INFRINGEMENT.
99
-
100
- 7. Limitation of Liability
101
-
102
- IN NO EVENT SHALL THE LICENSOR BE LIABLE FOR ANY CLAIM, DAMAGES, OR
103
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR
104
- OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE
105
- OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
106
-
107
- 8. Commercial Licensing
108
-
109
- For commercial licensing, redistribution, or any use not permitted
110
- under Section 1, contact: apicircle365@gmail.com
1
+ API Circle Studio License
2
+ Custom Source-Available License, v1.0
3
+
4
+ Copyright (c) 2026 Deva Prakash ("Licensor")
5
+
6
+ The source code in this repository ("the Software") is made available for
7
+ the purposes of transparency, security review, contribution, and personal
8
+ evaluation. This is NOT an open-source license as defined by the Open
9
+ Source Initiative.
10
+
11
+ 0. Definitions
12
+
13
+ "Commercial Use" means any use of the Software that is intended for
14
+ or directed toward commercial advantage or monetary compensation,
15
+ whether direct or indirect, including without limitation:
16
+
17
+ (a) using the Software to build, test, develop, deploy, or operate
18
+ any product, service, application, or system that is sold,
19
+ licensed, hosted, distributed, or otherwise made available to
20
+ any third party for a fee or other consideration;
21
+ (b) using the Software in the course of paid employment, paid
22
+ consulting, paid contracting, freelance work, or any other
23
+ revenue-generating activity, regardless of whether the Software
24
+ itself is sold or transferred;
25
+ (c) using the Software internally within a for-profit organization
26
+ beyond the Evaluation Period defined below;
27
+ (d) integrating the Software, or any portion of it, into any tool,
28
+ pipeline, automation, or workflow that supports the commercial
29
+ operations of any business;
30
+ (e) using the Software to provide a hosted, managed, or embedded
31
+ service of any kind to a third party, whether free or paid.
32
+
33
+ "Non-Commercial Use" means any use that is not Commercial Use,
34
+ including personal hobby projects, individual learning, academic
35
+ research, classroom instruction, and good-faith contribution to
36
+ this repository.
37
+
38
+ "Evaluation Period" means a single, continuous period of up to
39
+ thirty (30) days during which a for-profit organization may
40
+ internally evaluate the Software at no charge. After the Evaluation
41
+ Period expires, any further use of the Software by that organization
42
+ constitutes Commercial Use and requires a separate commercial
43
+ license from the Licensor.
44
+
45
+ 1. Permitted Use
46
+
47
+ You may, without charge:
48
+
49
+ (a) view, read, and study the source code of the Software;
50
+ (b) run the Software, in source or compiled form, for your own
51
+ Non-Commercial Use, or for Commercial Use solely within the
52
+ Evaluation Period;
53
+ (c) submit improvements to the Software back to this repository via
54
+ pull request, subject to Section 3 (Contributions).
55
+
56
+ 2. Prohibited Use
57
+
58
+ Without prior written permission from the Licensor, you may NOT:
59
+
60
+ (a) make any Commercial Use of the Software, in whole or in part,
61
+ except during the Evaluation Period as defined in Section 0;
62
+ (b) redistribute the Software, in source or compiled form, whether
63
+ modified or unmodified, to any third party;
64
+ (c) sublicense, sell, rent, lease, or otherwise transfer the
65
+ Software or any rights granted herein;
66
+ (d) remove, obscure, or alter any copyright, trademark, attribution,
67
+ or license notice contained in the Software;
68
+ (e) use the names "API Circle", "API Circle Studio", or any related
69
+ logos or trademarks, except as required for accurate attribution.
70
+
71
+ 3. Contributions
72
+
73
+ By submitting any contribution (including but not limited to code,
74
+ documentation, or assets) to this repository, you grant the Licensor
75
+ a perpetual, worldwide, irrevocable, royalty-free, sublicensable
76
+ license to use, modify, distribute, and relicense your contribution
77
+ under any terms, including the terms of this license or any future
78
+ version thereof.
79
+
80
+ 4. No Trademark License
81
+
82
+ This license does not grant permission to use the trade names,
83
+ trademarks, service marks, or product names of the Licensor, except
84
+ as required for reasonable and customary use in describing the
85
+ origin of the Software.
86
+
87
+ 5. Termination
88
+
89
+ The rights granted in Section 1 terminate automatically if you
90
+ breach any term of this license. Upon termination, you must cease
91
+ all use of the Software and destroy all copies in your possession.
92
+
93
+ 6. Disclaimer of Warranty
94
+
95
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
96
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
97
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
98
+ NON-INFRINGEMENT.
99
+
100
+ 7. Limitation of Liability
101
+
102
+ IN NO EVENT SHALL THE LICENSOR BE LIABLE FOR ANY CLAIM, DAMAGES, OR
103
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR
104
+ OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE
105
+ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
106
+
107
+ 8. Commercial Licensing
108
+
109
+ For commercial licensing, redistribution, or any use not permitted
110
+ under Section 1, contact: apicircle365@gmail.com
package/README.md CHANGED
@@ -4,41 +4,123 @@
4
4
 
5
5
  <h1 align="center">@apicircle/cli</h1>
6
6
 
7
- Command-line companion to [API Circle Studio](https://github.com/apicircle/studio). Run mock servers, drive the MCP server, import OpenAPI / Postman / Insomnia / curl into a workspace, and execute saved plans — all from any terminal, no Electron required.
7
+ <p align="center">
8
+ <strong>API Circle Studio, without the UI.</strong><br />
9
+ Mock servers, MCP, spec imports, headless plan runs, and multi-workspace management — every Studio feature your team needs in CI, scripts, and SSH sessions.
10
+ </p>
11
+
12
+ <p align="center">
13
+ <a href="https://www.npmjs.com/package/@apicircle/cli"><img src="https://img.shields.io/npm/v/@apicircle/cli?color=cb3837&logo=npm" alt="npm version" /></a>
14
+ <img src="https://img.shields.io/badge/subcommands-5-blue" alt="5 subcommands" />
15
+ <img src="https://img.shields.io/badge/runs-CI%20%C2%B7%20Docker%20%C2%B7%20SSH%20%C2%B7%20local-success" alt="Runs everywhere" />
16
+ <img src="https://img.shields.io/badge/node-%E2%89%A5%2020-brightgreen" alt="Node ≥ 20" />
17
+ </p>
18
+
19
+ ---
20
+
21
+ ## Why a CLI?
22
+
23
+ The Studio desktop app is great for authoring. But the moment you want to
24
+ **ship**, **schedule**, or **automate**, you need a binary. `@apicircle/cli`
25
+ is exactly that — every workflow the desktop app supports, accessible from
26
+ any terminal, container, or pipeline. No Electron, no GUI dependency, no
27
+ mouse required.
28
+
29
+ ```bash
30
+ # Spin up a mock from an OpenAPI spec — in one command
31
+ apicircle mock ./openapi.yaml --port 4040
32
+
33
+ # Run your saved smoke tests in CI, fail the build if they fail
34
+ apicircle run "Smoke Tests" --reporter junit
35
+
36
+ # Boot an MCP server so an AI assistant can drive your workspace
37
+ apicircle mcp
38
+ ```
8
39
 
9
40
  ## Install
10
41
 
11
42
  ```bash
12
43
  npm install -g @apicircle/cli
13
- # or use without installing
44
+ # or run without installing
14
45
  npx @apicircle/cli --help
15
46
  ```
16
47
 
17
- ## What's a "workspace folder"?
48
+ Single command, single binary: `apicircle`.
49
+
50
+ ## What you can do with it
51
+
52
+ | You need to… | Command |
53
+ | ------------------------------------------------- | ------------------------------------------------------------------- |
54
+ | List, create, switch between workspaces | `apicircle workspaces <list \| create \| use \| path>` |
55
+ | Run a local mock server from a spec file | `apicircle mock <spec> [--port] [--type] [--cors]` |
56
+ | Import a spec into a workspace | `apicircle import <openapi \| postman \| insomnia \| curl> <input>` |
57
+ | Execute a saved plan headlessly | `apicircle run <plan>` |
58
+ | Expose your workspace to an AI assistant over MCP | `apicircle mcp [--workspace-name \| --workspace-path]` |
18
59
 
19
- Several subcommands take `--workspace <dir>`. A _workspace folder_ is a
20
- directory containing two JSON files (`workspace.synced.json` and
21
- `workspace.local.json`) that together hold your collections, environments,
22
- mock-server definitions, and per-device runtime state.
60
+ ## Workspaces, in one minute
23
61
 
24
- **You get one by cloning a GitHub repo** created with the Desktop app's
25
- _Link to Git_ feature:
62
+ API Circle Studio is **multi-workspace by default**. A workspace is a
63
+ `{ synced, local }` pair of JSON documents — your collections, environments,
64
+ mock-server definitions, plans, history. You can have many on a single
65
+ machine; each is its own GitHub repo, environment set, etc.
66
+
67
+ There are two ways the CLI finds a workspace:
68
+
69
+ | Use case | How to point the CLI at it |
70
+ | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
71
+ | Workspaces created in the desktop app on this machine | `--workspace-name <name-or-id>` — registry lookup |
72
+ | A workspace directory not registered locally (CI, git-cloned repo) | `--workspace-path <dir>` — literal filesystem path |
73
+ | Whatever's currently active | omit both — CLI picks the active workspace from the registry, or the current directory if no registry exists |
74
+
75
+ The flags are **mutually exclusive** — passing both is an error.
76
+
77
+ The registry root defaults to the desktop app's userData:
78
+
79
+ - **Windows** — `%APPDATA%\@apicircle\desktop\workspaces\`
80
+ - **macOS** — `~/Library/Application Support/@apicircle/desktop/workspaces/`
81
+ - **Linux** — `~/.config/@apicircle/desktop/workspaces/`
82
+
83
+ Override with `APICIRCLE_WORKSPACES_ROOT` for CI / tests.
84
+
85
+ ## Subcommands
86
+
87
+ ### `apicircle workspaces` — manage the registry
26
88
 
27
89
  ```bash
28
- git clone https://github.com/<you>/<your-workspace-repo>
29
- apicircle mcp --workspace ./<your-workspace-repo>
90
+ apicircle workspaces list # every registered workspace + which is active
91
+ apicircle workspaces list --json # JSON for scripts
92
+ apicircle workspaces create "Petstore" # seed a new workspace + add to the registry
93
+ apicircle workspaces create "Sandbox" --sample # seed with one sample request
94
+ apicircle workspaces use Petstore # set the active workspace by name (or id)
95
+ apicircle workspaces path Petstore # print the on-disk path for one workspace
96
+ apicircle workspaces path # print the workspaces root
30
97
  ```
31
98
 
32
- If you don't have a workspace repo yet, open the **Desktop / Web app**
33
- the workspace is created automatically in browser storage, and the **Mocks**
34
- and **MCP** panels work directly inside the app with no folder required. Use
35
- the CLI for headless / CI scenarios where on-disk JSON is the right interface.
99
+ `workspaces use` resolves the same way as `--workspace-name`: case-insensitive
100
+ name match, falling back to id.
36
101
 
37
- ## Subcommands
102
+ ### `apicircle mcp` — boot the MCP stdio server
103
+
104
+ ```bash
105
+ # Multi-workspace mode (recommended) — expose every workspace via `workspace.list`
106
+ apicircle mcp
107
+
108
+ # Scope to one workspace
109
+ apicircle mcp --workspace-name Petstore
110
+
111
+ # Point at a workspace directory that isn't in the registry (CI / git-cloned)
112
+ apicircle mcp --workspace-path ./checkout-repo
113
+ ```
114
+
115
+ With no workspace flag, the server boots against the desktop app's registry
116
+ root and exposes **all** workspaces. AI clients see them through the
117
+ `workspace.list` tool; entity tools default to the active workspace and accept
118
+ an optional `workspaceId` to scope.
38
119
 
39
- ### `apicircle mock <spec>`
120
+ Wire this into Claude Desktop / Cursor / Codex / etc — see
121
+ [Connect your AI client](https://github.com/apicircle/studio/blob/main/docs/connect-your-ai-client.md).
40
122
 
41
- Boot a mock server from an OpenAPI / Postman / Insomnia file.
123
+ ### `apicircle mock <spec>` local mock server
42
124
 
43
125
  ```bash
44
126
  apicircle mock ./openapi.yaml --port 4040
@@ -46,46 +128,134 @@ apicircle mock ./postman_collection.json --type postman
46
128
  apicircle mock ./insomnia_export.json --type insomnia --cors=false
47
129
  ```
48
130
 
49
- The CLI binds to a free port unless `--port` is set, prints the URL, and runs until you `Ctrl-C`.
131
+ The CLI binds to a free port unless `--port` is set, prints the URL, and runs
132
+ until you `Ctrl-C`. This subcommand operates on a spec file directly — it does
133
+ **not** consult the workspace registry.
50
134
 
51
- ### `apicircle mcp [--workspace <dir>]`
135
+ Under the hood: `@apicircle/mock-server-core`, the same Hono engine the
136
+ desktop app uses.
52
137
 
53
- Start the MCP stdio server pointed at a workspace folder.
138
+ ### `apicircle import <type> <input>` import a spec
54
139
 
55
140
  ```bash
56
- apicircle mcp --workspace ./my-workspace
57
- APICIRCLE_WORKSPACE=./my-workspace apicircle mcp
58
- ```
141
+ # Active workspace (or current directory when no registry exists)
142
+ apicircle import openapi ./spec.yaml --format yaml
143
+
144
+ # Named registered workspace
145
+ apicircle import postman ./col.json --workspace-name Petstore
146
+ apicircle import insomnia ./exp.json --workspace-name Petstore
59
147
 
60
- If `--workspace` is omitted, the current directory is used. The directory is auto-initialized with an empty `workspace.synced.json` + `workspace.local.json` on first run.
148
+ # Workspace dir not in the registry
149
+ apicircle import openapi ./spec.yaml --workspace-path ./checkout-repo
61
150
 
62
- Wire this into Claude Desktop / Cursor / etc — see [Connect your AI client](https://github.com/apicircle/studio/blob/main/docs/connect-your-ai-client.md).
151
+ # Read from stdin
152
+ apicircle import openapi - --workspace-name Petstore < ./spec.yaml
153
+ ```
63
154
 
64
- ### `apicircle import <type> <input>`
155
+ `<type>` is `curl`, `openapi`, `postman`, or `insomnia`. Each import appends
156
+ one request per operation / item — your existing folder structure stays intact.
65
157
 
66
- Import a spec into a workspace folder.
158
+ ### `apicircle run <plan>` — execute a saved plan headlessly
67
159
 
68
160
  ```bash
69
- apicircle import openapi ./spec.yaml --workspace ./ws --format yaml
70
- apicircle import postman ./col.json --workspace ./ws
71
- apicircle import insomnia ./exp.json --workspace ./ws
72
- apicircle import curl ./curl.txt --workspace ./ws
73
- apicircle import openapi - --workspace ./ws < ./spec.yaml
161
+ apicircle run "Smoke Tests" --reporter junit
162
+ apicircle run plan_a1b2c3 --env staging --bail --workspace-name Petstore
163
+ apicircle run "Nightly" --secrets ./secrets.json --no-save
74
164
  ```
75
165
 
76
- Each import appends one request per operation/item to `workspace.synced.json`.
166
+ Resolves a plan by name or id, runs each step through the **real** request
167
+ engine (same auth, same retries, same assertions as the desktop app),
168
+ evaluates assertions, and carries extracted context forward between steps.
169
+
170
+ **Flags:**
171
+
172
+ - `--reporter text|json|junit` — output format; `junit` is ready for CI test reporters.
173
+ - `--bail` — stop at the first failed step.
174
+ - `--env <name>` — layer an environment onto the run.
175
+ - `--secrets <file>` or `APICIRCLE_SECRET_*` env vars — supply encrypted variables.
176
+ - `--no-save` — don't write the run to history.
177
+ - `--no-assertions` — execute requests but skip assertions.
178
+ - `--as <actor>` — override the recorded runner identity.
179
+
180
+ **Exit codes:** `0` every step passed, `1` a step failed (or the run was
181
+ aborted), `2` usage error, `3` denied by the authorization gate. Pipelines
182
+ gate on it directly.
77
183
 
78
- ### `apicircle run <plan>`
184
+ ## Common workflows
79
185
 
80
- Execute a saved workspace execution plan headlessly and report pass/fail.
186
+ **Set up a new workspace from scratch**
81
187
 
82
188
  ```bash
189
+ apicircle workspaces create "Internal API"
190
+ apicircle import openapi ./internal-api.yaml --workspace-name "Internal API"
191
+ apicircle mcp --workspace-name "Internal API"
192
+ ```
193
+
194
+ **CI gate against a git-cloned workspace repo**
195
+
196
+ ```bash
197
+ git clone github.com/me/checkout-workspace.git
198
+ cd checkout-workspace
83
199
  apicircle run "Smoke Tests" --reporter junit
84
- apicircle run plan_a1b2c3 --env staging --bail
85
- apicircle run "Nightly" --secrets ./secrets.json --no-save
86
200
  ```
87
201
 
88
- Resolves a plan by name or id, runs each step through the real request engine, evaluates assertions, and carries extracted context forward. Flags: `--reporter text|json|junit`, `--bail` (stop at the first failed step), `--env <name>` (layer an environment onto the run), `--secrets <file>` or `APICIRCLE_SECRET_*` env vars (encrypted variables), `--no-save`, `--no-assertions`. Exit codes: `0` pass, `1` fail, `2` usage error, `3` run denied.
202
+ (No `--workspace-path` needed when running inside the workspace directory
203
+ the CLI's cwd fallback picks it up automatically.)
204
+
205
+ **Mock a third-party API for the duration of your test suite**
206
+
207
+ ```bash
208
+ apicircle mock ./stripe-openapi.yaml --port 4242 &
209
+ MOCK_PID=$!
210
+
211
+ npm test
212
+ RESULT=$?
213
+
214
+ kill $MOCK_PID
215
+ exit $RESULT
216
+ ```
217
+
218
+ **Switch the active workspace and verify**
219
+
220
+ ```bash
221
+ apicircle workspaces use Sandbox
222
+ apicircle workspaces list
223
+ # Sandbox now shows ● next to it.
224
+ ```
225
+
226
+ ## Use cases
227
+
228
+ - **CI / CD gates** — run smoke tests, contract tests, or full regression
229
+ plans against staging before promoting to prod.
230
+ - **Mock-driven local dev** — `apicircle mock` in a side terminal, your
231
+ frontend pointed at it, your backend team unblocked.
232
+ - **Headless onboarding** — `apicircle import openapi <url>` turns a public
233
+ spec into a typed, runnable workspace in seconds.
234
+ - **AI-assistant wiring on servers** — boot `apicircle mcp` in a remote
235
+ session so a headless agent can drive the workspace.
236
+ - **Workspace migration & backup** — `workspaces path` + `tar` = a clean
237
+ on-disk archive any other machine can pick up.
238
+
239
+ ## Where it fits
240
+
241
+ ```
242
+ @apicircle/shared (types + utilities)
243
+ @apicircle/core (request engine + auth + imports + workspace I/O)
244
+ @apicircle/mock-server-core (mock-server engine)
245
+ @apicircle/mcp-server (MCP host + tool catalog)
246
+ └── @apicircle/cli ◀── you are here
247
+ ```
248
+
249
+ Every subcommand is a thin wrapper around one of the sister packages — same
250
+ behaviour as the desktop app, same on-disk format. An edit made by the CLI
251
+ is visible to the desktop app on the next read, and vice versa.
252
+
253
+ ## Stability
254
+
255
+ Each subcommand is exercised by both unit tests and Playwright-driven E2E
256
+ suites; the same engine runs in **1,900+ tests** across the wider Studio
257
+ codebase. Exit codes and JSON output shapes are part of the contract — gates
258
+ that pass today will keep passing as long as the major version doesn't change.
89
259
 
90
260
  ## License
91
261