specshield 1.0.7 → 1.0.9

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.
Files changed (2) hide show
  1. package/README.md +287 -519
  2. package/package.json +32 -24
package/README.md CHANGED
@@ -3,605 +3,430 @@
3
3
  [![npm](https://img.shields.io/npm/v/specshield)](https://www.npmjs.com/package/specshield)
4
4
  [![downloads](https://img.shields.io/npm/dw/specshield)](https://www.npmjs.com/package/specshield)
5
5
  [![license](https://img.shields.io/badge/license-MIT-blue)](#license)
6
- [![node](https://img.shields.io/badge/node-%3E%3D18-green)](https://nodejs.org)
7
-
8
- Compare OpenAPI and Swagger specs, detect breaking changes, and fail CI before incompatible API changes reach production.
6
+ [![node](https://img.shields.io/badge/node-%3E%3D20-green)](https://nodejs.org)
9
7
 
10
8
  ---
11
9
 
12
- ## Table of Contents
13
-
14
- - [What is SpecShield CLI?](#what-is-specshield-cli)
15
- - [Installation](#installation)
16
- - [Local Compare](#local-compare)
17
- - [Authentication](#authentication)
18
- - [Generate an API Token](#generate-an-api-token)
19
- - [Remote Compare](#remote-compare)
20
- - [Contracts — Consumer-Driven Testing](#contracts--consumer-driven-testing)
21
- - [Contract File Format](#contract-file-format)
22
- - [Publish a Contract](#publish-a-contract)
23
- - [List Contracts](#list-contracts)
24
- - [Get Latest Contract](#get-latest-contract)
25
- - [Verify a Contract](#verify-a-contract)
26
- - [Verification History](#verification-history)
27
- - [Can I Deploy?](#can-i-deploy)
28
- - [Full Publish → Verify → Deploy Workflow](#full-publish--verify--deploy-workflow)
29
- - [Contracts in CI/CD](#contracts-in-cicd)
30
- - [Config File](#config-file)
31
- - [All Options](#all-options)
32
- - [Exit Codes](#exit-codes)
33
- - [CI/CD — GitHub Actions](#cicd--github-actions)
34
- - [Support](#support)
10
+ > **OpenAPI Diff · Swagger Diff · API Breaking Change Detection · Contract Testing · Pact Alternative · API Governance · CI/CD API Validation · API Drift Detection**
35
11
 
36
12
  ---
37
13
 
38
- ## What is SpecShield CLI?
39
-
40
- SpecShield CLI is a command-line tool for comparing two OpenAPI/Swagger specifications and detecting what changed between them. It classifies changes into:
14
+ ## Stop Breaking APIs in Production
41
15
 
42
- - **Breaking changes** removed endpoints, changed required fields, incompatible type changes
43
- - **Modifications** changed behavior that may or may not break clients
44
- - **Additions** — new endpoints or fields
45
- - **Warnings** — low-severity notices
16
+ **SpecShield** detects breaking API changes and runs contract tests directly in your CI/CD pipeline —
17
+ before they become production incidents.
46
18
 
47
- It works in two modes:
19
+ ```
20
+ OpenAPI diff + contract testing + deployment gating — in one CLI.
21
+ ```
48
22
 
49
- | Mode | Description |
50
- |---|---|
51
- | **Local** | Compares two spec files on your machine. No account needed. |
52
- | **Remote** | Sends specs to the SpecShield hosted API. Requires an API token. Results are stored in your dashboard. |
23
+ No broker. No complex setup. Works in 30 seconds.
53
24
 
54
25
  ---
55
26
 
56
- ## Installation
27
+ ## The Problem
57
28
 
58
- ```bash
59
- npm install -g specshield
60
- ```
29
+ **APIs break silently. Your users feel it first.**
61
30
 
62
- Verify the installation:
31
+ - A backend developer renames a field — the mobile app crashes for 10,000 users
32
+ - An endpoint gets removed — the frontend breaks with no error in your logs
33
+ - A required field changes — partner integrations start failing at 2am
34
+ - You only find out after a production incident, a 3am alert, or an angry customer
63
35
 
64
- ```bash
65
- specshield --version
66
- ```
36
+ Manual code review doesn't catch this. Integration tests run too late.
37
+ **You need a contract between your services — and something that enforces it.**
67
38
 
68
39
  ---
69
40
 
70
- ## Local Compare
41
+ ## The Solution
71
42
 
72
- No account or token required for local comparisons.
43
+ Think of SpecShield as **unit tests for your API contracts**.
44
+
45
+ - The consumer declares what it expects from the provider
46
+ - The provider proves it satisfies those expectations before deploying
47
+ - SpecShield blocks the deployment if anything breaks
73
48
 
74
- ```bash
75
- specshield compare base.yaml target.yaml
49
+ ```
50
+ Consumer publishes contract → Provider verifies it → CI either passes or blocks
76
51
  ```
77
52
 
78
- Fail CI if breaking changes are found:
53
+ No runtime surprise. No production incident. No 3am page.
79
54
 
80
- ```bash
81
- specshield compare base.yaml target.yaml --fail-on-breaking
82
- ```
55
+ ---
83
56
 
84
- Output as JSON:
57
+ ## See It in Action
85
58
 
86
59
  ```bash
87
- specshield compare base.yaml target.yaml --json
88
- ```
60
+ $ specshield compare base.yaml target.yaml --fail-on-breaking
89
61
 
90
- Save results to a file:
62
+ BREAKING CHANGES DETECTED
91
63
 
92
- ```bash
93
- specshield compare base.yaml target.yaml --output result.json
94
- ```
64
+ 1. DELETE /users endpoint removed
65
+ 2. POST /payments "amount" changed from optional to required
66
+ 3. GET /orders/{id} — "status" type changed: string → object
95
67
 
96
- Ignore specific changes:
68
+ Breaking changes : 3
69
+ Modifications : 1
70
+ Additions : 2
97
71
 
98
- ```bash
99
- specshield compare base.yaml target.yaml --ignore "DELETE /users removed" --fail-on-breaking
72
+ CI Result: FAILED · Exit code: 1
100
73
  ```
101
74
 
102
- ---
75
+ **That 3-line output just saved you a production incident.**
103
76
 
104
- ## Authentication
77
+ And when everything is safe:
105
78
 
106
- Remote compare requires a SpecShield account and an API token.
79
+ ```bash
80
+ $ specshield compare base.yaml target.yaml --fail-on-breaking
107
81
 
108
- ### Sign in to SpecShield
82
+ NO BREAKING CHANGES FOUND
109
83
 
110
- 1. Go to [https://specshield.io](https://specshield.io)
111
- 2. Sign in with your email/password, GitHub, or Google account
112
- 3. You will land on your account dashboard
84
+ Breaking changes : 0
85
+ Modifications : 0
86
+ Additions : 3
113
87
 
114
- ### Generate an API Token
88
+ CI Result: PASSED · Exit code: 0
89
+ ```
115
90
 
116
- 1. From your dashboard, go to **Account → API Keys**
117
- (direct link: [https://specshield.io/account/keys](https://specshield.io/account/keys))
118
- 2. Click **Generate API Key**
119
- 3. Copy the token — it starts with `ss_` and is shown only once
120
- 4. Store it securely (password manager, secrets vault, or CI/CD secret)
91
+ ---
121
92
 
122
- ### Configure the CLI
93
+ ## Quick Start
123
94
 
124
- Run the login command with your token:
95
+ No account. No login. No config file. Just run it.
125
96
 
126
97
  ```bash
127
- specshield login --api-key ss_your_token_here
98
+ npm install -g specshield
128
99
  ```
129
100
 
130
- This validates the token against the SpecShield API and saves it to `~/.specshield/config.json`. You will not need to pass the token on every command after this.
131
-
132
- **Example output:**
133
-
101
+ ```bash
102
+ specshield compare base.yaml target.yaml --fail-on-breaking
134
103
  ```
135
- ✔ Logged in successfully.
136
104
 
137
- Customer: Jane Smith
138
- Plan: FREE
139
- Config: /Users/jane/.specshield/config.json
105
+ That's it. Works with any OpenAPI 3.x YAML or JSON spec.
140
106
 
141
- Run: specshield compare base.yaml target.yaml --remote
142
- ```
107
+ ---
143
108
 
144
- ### Alternative: Environment Variable
109
+ ## 🚀 Create Your Free Account
145
110
 
146
- If you prefer not to use the stored config (e.g. in CI/CD), set the token as an environment variable:
111
+ **Unlock history, dashboards, contract testing, and team features.**
147
112
 
148
- ```bash
149
- export SPECSHIELD_API_KEY=ss_your_token_here
150
- specshield compare base.yaml target.yaml --remote
151
- ```
113
+ 👉 **[Create free account at specshield.io](https://specshield.io)**
152
114
 
153
- The token resolution order is:
115
+ - No credit card required
116
+ - ✅ Takes less than 30 seconds
117
+ - ✅ GitHub and Google sign-in supported
118
+ - ✅ Local compare always free, forever
154
119
 
155
- 1. `--api-key` flag (highest priority)
156
- 2. `SPECSHIELD_API_KEY` environment variable
157
- 3. Stored config (`~/.specshield/config.json`)
158
- 4. `remote.apiKey` in `.specshield.yml`
120
+ ---
159
121
 
160
- ### Log Out
122
+ ## Local vs Cloud
161
123
 
162
- To remove the stored token:
124
+ | Feature | Local (Free) | Cloud (specshield.io) |
125
+ |---|---|---|
126
+ | Compare two spec files | ✅ | ✅ |
127
+ | Breaking change detection | ✅ | ✅ |
128
+ | JSON / human output | ✅ | ✅ |
129
+ | Fail CI on breaking change | ✅ | ✅ |
130
+ | **Compare history & dashboard** | ❌ | ✅ |
131
+ | **Contract testing registry** | ❌ | ✅ |
132
+ | **can-i-deploy gating** | ❌ | ✅ |
133
+ | **Team collaboration** | ❌ | ✅ |
134
+ | **API drift trends** | ❌ | ✅ |
163
135
 
164
- ```bash
165
- specshield logout
166
- ```
136
+ Local is great for getting started. Cloud is what your team ships with.
167
137
 
168
138
  ---
169
139
 
170
- ## Remote Compare
140
+ ## A Real-World Story
141
+
142
+ > The `payment-service` team merged a change that renamed `status` to `paymentStatus`
143
+ > in the payment creation response. The `checkout-ui` team wasn't notified.
144
+ >
145
+ > Without SpecShield, this would have reached staging, broken checkout for every user,
146
+ > and triggered an incident at 2am.
147
+ >
148
+ > With SpecShield, the provider's CI ran `specshield contracts verify` against the
149
+ > consumer's published contract. The mismatch was caught immediately:
150
+ >
151
+ > ```
152
+ > ● MISSING_FIELD at $.status
153
+ > expected: "CREATED" → actual: null
154
+ > ```
155
+ >
156
+ > `can-i-deploy` returned exit code `1`. The broken build never deployed.
157
+ > **Zero users affected.**
171
158
 
172
- Remote compare sends your spec files to the SpecShield hosted API at [https://specshield.io](https://specshield.io). Results are processed server-side and stored in your dashboard for review.
159
+ ---
173
160
 
174
- **When to use remote mode:**
175
- - You want comparison history tracked in the SpecShield dashboard
176
- - Your team shares a centralized view of API drift over time
177
- - You are on a plan with advanced reporting features
161
+ ## Use Cases
178
162
 
179
- ### Basic remote compare
163
+ **Pull Request Validation**
164
+ Catch breaking changes before they're merged. Run `specshield compare` against your base branch on every PR.
180
165
 
181
- ```bash
182
- specshield compare base.yaml target.yaml --remote
183
- ```
184
-
185
- ### Remote compare with CI fail on breaking changes
186
-
187
- ```bash
188
- specshield compare base.yaml target.yaml --remote --fail-on-breaking
189
- ```
166
+ **CI/CD Gating**
167
+ Fail the build automatically when a breaking change is detected. Exit code `1` triggers your pipeline to stop.
190
168
 
191
- ### Remote compare with JSON output
169
+ **Microservices Contract Safety**
170
+ Consumer teams publish what they expect. Provider teams verify they deliver it. No cross-team surprises.
192
171
 
193
- ```bash
194
- specshield compare base.yaml target.yaml --remote --json --output result.json
195
- ```
172
+ **API Governance**
173
+ Track API drift over time across your entire platform. Know what changed, when, and which team changed it.
196
174
 
197
- ### How authentication works in remote mode
175
+ ---
198
176
 
199
- The CLI reads your API token (from flag, env var, or stored config) and sends it as an `X-Api-Key` header with each request. If no token is found, the command exits with an error:
177
+ ## vs. Alternatives
200
178
 
201
- ```
202
- Error: No API key found. Run: specshield login --api-key <KEY>
203
- ```
179
+ | Feature | SpecShield | Pact | openapi-diff |
180
+ |---|---|---|---|
181
+ | OpenAPI / Swagger native | ✅ | ❌ (code-level) | ✅ |
182
+ | No broker required | ✅ | ❌ (needs Pact Broker) | ✅ |
183
+ | Contract testing | ✅ | ✅ | ❌ |
184
+ | Breaking change detection | ✅ | ❌ | ✅ |
185
+ | can-i-deploy gating | ✅ | ✅ (via broker) | ❌ |
186
+ | Hosted dashboard | ✅ | ✅ (Pactflow, paid) | ❌ |
187
+ | Team collaboration | ✅ | ✅ (paid) | ❌ |
188
+ | CLI-first workflow | ✅ | ❌ | ✅ |
189
+ | Free hosted tier | ✅ | ❌ | N/A |
204
190
 
205
191
  ---
206
192
 
207
- ---
193
+ ## 🎥 Demo
208
194
 
209
- ## Contracts — Consumer-Driven Testing
195
+ ![SpecShield CLI Demo](demo/specshield-demo.gif)
210
196
 
211
- SpecShield Contracts lets consumer teams publish API expectations (contracts) to a central registry. Provider teams then verify their service satisfies those contracts before deploying.
197
+ > `specshield compare payment-api-v1.yaml payment-api-v2.yaml --fail-on-breaking`
212
198
 
213
- **Why contract testing?**
214
- - Catch provider-side regressions before they reach consumers
215
- - Enforce an agreed-upon API shape across services
216
- - Gate deployments on verified contracts with `can-i-deploy`
199
+ ---
217
200
 
218
- All contract commands require an API token. See [Authentication](#authentication).
201
+ ## Pricing
219
202
 
220
- ---
203
+ | Plan | Price | What's included |
204
+ |---|---|---|
205
+ | **Free** | $0 forever | Local compare, unlimited. Cloud: compare history, API keys, dashboard |
206
+ | **Pro** | Coming soon | Team collaboration, advanced reporting, priority support |
221
207
 
222
- ### Contract File Format
208
+ No credit card ever required for the free plan.
209
+ **[Get started free →](https://specshield.io)**
223
210
 
224
- Create a `.json` file describing the expected API interactions:
211
+ ---
225
212
 
226
- ```json
227
- {
228
- "consumer": {
229
- "name": "checkout-ui",
230
- "version": "1.2.0"
231
- },
232
- "provider": {
233
- "name": "payment-service"
234
- },
235
- "contractName": "create-payment",
236
- "contractType": "HTTP",
237
- "interactions": [
238
- {
239
- "description": "create payment",
240
- "request": {
241
- "method": "POST",
242
- "path": "/payments",
243
- "headers": {
244
- "Content-Type": "application/json"
245
- },
246
- "body": {
247
- "orderId": "ORD-123",
248
- "amount": 100,
249
- "currency": "INR"
250
- }
251
- },
252
- "expectedResponse": {
253
- "status": 201,
254
- "headers": {
255
- "Content-Type": "application/json"
256
- },
257
- "body": {
258
- "paymentId": "PAY-123",
259
- "status": "CREATED"
260
- }
261
- }
262
- }
263
- ],
264
- "metadata": {
265
- "generatedBy": "specshield-cli",
266
- "contractFormatVersion": "1.0"
267
- }
268
- }
269
- ```
213
+ ## Login & Authentication
270
214
 
271
- The `consumer.name`, `provider.name`, and `contractName` fields are used to identify the contract in the registry. CLI flags (`--consumer`, `--provider`, `--contract-name`) override file values if provided.
215
+ **Step 1 Create your account**
272
216
 
273
- ---
217
+ Go to [https://specshield.io](https://specshield.io) · Sign in with GitHub or Google (30 seconds)
274
218
 
275
- ### Publish a Contract
219
+ **Step 2 Generate an API key**
276
220
 
277
- ```bash
278
- specshield contracts publish \
279
- --file ./contracts/create-payment.json \
280
- --org acme
281
- ```
221
+ Dashboard → **API Keys** → **Generate Key** · Copy the `ss_` token
282
222
 
283
- With all flags explicitly set (flags override file values):
223
+ **Step 3 Authenticate the CLI**
284
224
 
285
225
  ```bash
286
- specshield contracts publish \
287
- --file ./contracts/create-payment.json \
288
- --org acme \
289
- --consumer checkout-ui \
290
- --provider payment-service \
291
- --contract-name create-payment \
292
- --consumer-version 1.2.0 \
293
- --tag main
226
+ specshield login --api-key ss_your_token_here
294
227
  ```
295
228
 
296
- **Example output:**
297
-
298
229
  ```
299
- Contract Published Successfully
300
- ─────────────────────────────────────────────────────
301
- Contract ID : 42
302
- Contract Name : create-payment
303
- Consumer : checkout-ui
304
- Provider : payment-service
305
- Version : 3
306
- Status : PUBLISHED
307
- Content Hash : a3f9c1d2e7b8...
308
- Published At : 06/04/2026 14:30:00
309
-
310
- ➜ Run: specshield contracts verify --contract-id 42 --base-url http://localhost:8080
230
+ Logged in successfully.
231
+ Customer : Your Name
232
+ Plan : FREE
311
233
  ```
312
234
 
313
- **Options:**
314
-
315
- | Flag | Description |
316
- |---|---|
317
- | `--file <path>` | Path to contract JSON file (required) |
318
- | `--org <key>` | Organization key |
319
- | `--consumer <key>` | Consumer service key (overrides file) |
320
- | `--provider <key>` | Provider service key (overrides file) |
321
- | `--consumer-version <ver>` | Consumer version tag |
322
- | `--contract-name <name>` | Contract name (overrides file) |
323
- | `--tag <tag>` | Git branch or release tag |
324
- | `--server <url>` | SpecShield server URL (default: `https://specshield.io`) |
325
- | `--api-token <token>` | API token |
326
-
327
- ---
235
+ Done. Your token is stored in `~/.specshield/config.json` — no need to pass it on every command.
328
236
 
329
- ### List Contracts
237
+ **Or use an environment variable (recommended for CI):**
330
238
 
331
239
  ```bash
332
- specshield contracts list
240
+ export SPECSHIELD_API_KEY=ss_your_token_here
333
241
  ```
334
242
 
335
- Filter by provider:
243
+ Token resolution order: `--api-key flag` → `SPECSHIELD_API_KEY` env var → stored config → `.specshield.yml`
336
244
 
337
- ```bash
338
- specshield contracts list --provider payment-service
339
- ```
340
-
341
- Filter by consumer, org, status:
245
+ ---
342
246
 
343
- ```bash
344
- specshield contracts list \
345
- --consumer checkout-ui \
346
- --provider payment-service \
347
- --status PUBLISHED
348
- ```
247
+ ## Local Compare
349
248
 
350
- Output raw JSON:
249
+ No account needed.
351
250
 
352
251
  ```bash
353
- specshield contracts list --json
354
- ```
355
-
356
- **Example output:**
252
+ # Basic compare
253
+ specshield compare base.yaml target.yaml
357
254
 
358
- ```
359
- SpecShield Contract Registry
360
- ─────────────────────────────────────────────────────
361
- Showing 2 of 2 contracts
255
+ # Fail CI on breaking changes
256
+ specshield compare base.yaml target.yaml --fail-on-breaking
362
257
 
363
- ID Contract Name Consumer Provider Ver Status Last Verify Published
364
- ── ─────────────── ──────────── ─────────────── ─── ───────── ─────────── ─────────────────────
365
- 42 create-payment checkout-ui payment-service 3 PUBLISHED SUCCESS 06/04/2026 14:30:00
366
- 41 get-order-status order-ui order-service 1 PUBLISHED FAILED 05/04/2026 09:15:00
367
- ```
258
+ # JSON output
259
+ specshield compare base.yaml target.yaml --json
368
260
 
369
- **Options:**
261
+ # Save to file
262
+ specshield compare base.yaml target.yaml --output result.json
370
263
 
371
- | Flag | Description |
372
- |---|---|
373
- | `--consumer <key>` | Filter by consumer |
374
- | `--provider <key>` | Filter by provider |
375
- | `--org <key>` | Filter by organization |
376
- | `--status <status>` | Filter by status (`PUBLISHED` / `DEPRECATED`) |
377
- | `--contract-name <name>` | Filter by contract name |
378
- | `--page <n>` | Page number (0-based, default: `0`) |
379
- | `--size <n>` | Page size (default: `20`) |
380
- | `--json` | Output raw JSON |
264
+ # Ignore a specific change
265
+ specshield compare base.yaml target.yaml --ignore "DELETE /admin removed" --fail-on-breaking
266
+ ```
381
267
 
382
268
  ---
383
269
 
384
- ### Get Latest Contract
270
+ ## Remote Compare
271
+
272
+ Sends your specs to SpecShield and stores results in your dashboard.
273
+ Requires a free account and API key.
385
274
 
386
275
  ```bash
387
- specshield contracts latest \
388
- --consumer checkout-ui \
389
- --provider payment-service \
390
- --contract-name create-payment
391
- ```
276
+ # Remote compare
277
+ specshield compare base.yaml target.yaml --remote
392
278
 
393
- Print the full contract content (interactions, body, etc.):
279
+ # Remote + fail on breaking
280
+ specshield compare base.yaml target.yaml --remote --fail-on-breaking
394
281
 
395
- ```bash
396
- specshield contracts latest \
397
- --consumer checkout-ui \
398
- --provider payment-service \
399
- --json
282
+ # Remote + JSON output saved to file
283
+ specshield compare base.yaml target.yaml --remote --json --output result.json
400
284
  ```
401
285
 
402
- **Options:**
286
+ ---
403
287
 
404
- | Flag | Description |
405
- |---|---|
406
- | `--consumer <key>` | Consumer service key |
407
- | `--provider <key>` | Provider service key |
408
- | `--org <key>` | Organization key |
409
- | `--contract-name <name>` | Contract name |
410
- | `--json` | Print full contract JSON |
288
+ ## Contract Testing
411
289
 
412
- ---
290
+ Consumer-driven contract testing for microservices — without a broker.
413
291
 
414
- ### Verify a Contract
292
+ **How it works:**
415
293
 
416
- Run the contract against a live provider. SpecShield replays each interaction against the `--base-url` and compares the response to the expected values.
294
+ 1. Consumer team publishes a contract (what they expect from the provider)
295
+ 2. Provider team verifies their service satisfies it
296
+ 3. `can-i-deploy` gates the deployment based on verification results
417
297
 
418
- ```bash
419
- specshield contracts verify \
420
- --contract-id 42 \
421
- --base-url http://localhost:8080
298
+ ### Contract File Format
299
+
300
+ ```json
301
+ {
302
+ "consumer": { "name": "checkout-ui", "version": "2.0.0" },
303
+ "provider": { "name": "payment-service" },
304
+ "orgKey": "acme-store",
305
+ "contractName": "create-payment",
306
+ "contractType": "HTTP",
307
+ "interactions": [
308
+ {
309
+ "description": "checkout-ui creates a payment",
310
+ "request": {
311
+ "method": "POST",
312
+ "path": "/payments",
313
+ "headers": { "Content-Type": "application/json" },
314
+ "body": { "orderId": "ORD-123", "amount": 1299, "currency": "INR" }
315
+ },
316
+ "expectedResponse": {
317
+ "status": 201,
318
+ "headers": { "Content-Type": "application/json" },
319
+ "body": { "paymentId": "PAY-123", "status": "CREATED" }
320
+ }
321
+ }
322
+ ]
323
+ }
422
324
  ```
423
325
 
424
- With version and environment tags:
326
+ ### Publish a Contract
425
327
 
426
328
  ```bash
427
- specshield contracts verify \
428
- --contract-id 42 \
429
- --base-url https://payment-service.staging.internal \
430
- --provider-version v2.1.0 \
431
- --env staging
329
+ specshield contracts publish \
330
+ --file ./contracts/create-payment.json \
331
+ --org acme-store \
332
+ --consumer-version 2.0.0 \
333
+ --tag main
432
334
  ```
433
335
 
434
- Output raw JSON (for CI parsing):
336
+ ### Verify a Contract
435
337
 
436
338
  ```bash
437
339
  specshield contracts verify \
438
340
  --contract-id 42 \
439
341
  --base-url http://localhost:8080 \
440
- --json
342
+ --provider-version v2.1.0 \
343
+ --env staging
441
344
  ```
442
345
 
443
- **Example output (pass):**
444
-
346
+ Pass output:
445
347
  ```
446
348
  ✔ Verification PASSED (1/1 interactions)
447
- ─────────────────────────────────────────────────────
448
- Verification ID : 101
449
- Contract ID : 42
450
- Status : SUCCESS
451
- Started At : 06/04/2026 14:35:00
452
- Completed At : 06/04/2026 14:35:01
453
-
454
- ➜ Run: specshield contracts can-i-deploy --provider payment-service --version v2.1.0
455
349
  ```
456
350
 
457
- **Example output (fail):**
458
-
351
+ Fail output:
459
352
  ```
460
353
  ✖ Verification FAILED (0/1 interactions passed, 1 failed)
461
- ─────────────────────────────────────────────────────
462
- Verification ID : 102
463
- Contract ID : 42
464
- Status : FAILED
465
354
 
466
355
  Mismatches
467
- ─────────────────────────────────────────────────────
468
- [create payment] STATUS_CODE_MISMATCH at $.status
469
- expected: 201 → actual: 200
470
- Expected status 201 but got 200
471
-
472
- ➜ Run: specshield contracts history --contract-id 42 to inspect previous runs
473
- ```
474
-
475
- **Exit codes:** `0` = PASSED, `1` = FAILED, `2` = error
476
-
477
- **Options:**
478
-
479
- | Flag | Description |
480
- |---|---|
481
- | `--contract-id <id>` | Contract ID to verify (required) |
482
- | `--base-url <url>` | Provider base URL (required, e.g. `http://localhost:8080`) |
483
- | `--provider-version <ver>` | Provider version tag |
484
- | `--env <environment>` | Environment label (`staging`, `qa`, `production`) |
485
- | `--mode <mode>` | `LIVE` or `REPLAY` (default: `LIVE`) |
486
- | `--json` | Output raw JSON |
487
-
488
- ---
489
-
490
- ### Verification History
491
-
492
- ```bash
493
- specshield contracts history --contract-id 42
494
- ```
495
-
496
- **Example output:**
497
-
356
+ ● [create payment] MISSING_FIELD at $.status
357
+ expected: "CREATED" → actual: null
498
358
  ```
499
- Verification History — Contract 42
500
- ─────────────────────────────────────────────────────
501
-
502
- ID Status Environment Provider Version Mode Completed At
503
- ─── ─────── ─────────── ──────────────── ──── ─────────────────────
504
- 102 FAILED staging v2.1.0 LIVE 06/04/2026 14:35:01
505
- 101 SUCCESS staging v2.0.0 LIVE 05/04/2026 10:00:00
506
- 98 SUCCESS qa v1.9.0 LIVE 01/04/2026 08:30:00
507
- ```
508
-
509
- **Options:**
510
-
511
- | Flag | Description |
512
- |---|---|
513
- | `--contract-id <id>` | Contract ID (required) |
514
- | `--json` | Output raw JSON |
515
-
516
- ---
517
359
 
518
360
  ### Can I Deploy?
519
361
 
520
- Check whether a provider version has passing verifications for all associated contracts:
521
-
522
- ```bash
523
- specshield contracts can-i-deploy \
524
- --provider payment-service \
525
- --version v2.1.0
526
- ```
527
-
528
- Scoped to a specific environment:
529
-
530
362
  ```bash
531
363
  specshield contracts can-i-deploy \
532
364
  --provider payment-service \
533
365
  --version v2.1.0 \
534
- --env production
366
+ --env staging
535
367
  ```
536
368
 
537
- **Example output (allowed):**
538
-
539
369
  ```
540
- ✔ PASS: payment-service v2.1.0 is deployable in production
541
- ─────────────────────────────────────────────────────
542
-
543
- Contract Decisions
544
- ✔ Contract ID 42 — SUCCESS
545
- All contracts verified
370
+ ✔ PASS: payment-service v2.1.0 is deployable in staging
546
371
  ```
547
-
548
- **Example output (blocked):**
549
-
550
372
  ```
551
- ✖ FAIL: payment-service v2.1.0 is NOT deployable in production
552
- ─────────────────────────────────────────────────────
373
+ ✖ FAIL: payment-service v2.1.0 is NOT deployable in staging
374
+ ```
375
+
376
+ Exit codes: `0` = deployable · `1` = blocked · `2` = error
553
377
 
554
- Contract Decisions
555
- ✖ Contract ID 43 — FAILED
556
- Unverified or failed contracts found
378
+ ### List and Inspect Contracts
557
379
 
558
- ➜ Run: specshield contracts verify --contract-id 43 --base-url <URL>
559
- ➜ to verify pending contracts before deploying
380
+ ```bash
381
+ specshield contracts list --provider payment-service
382
+ specshield contracts latest --consumer checkout-ui --provider payment-service --json
383
+ specshield contracts history --contract-id 42
560
384
  ```
561
385
 
562
- **Exit codes:** `0` = deployable, `1` = blocked, `2` = error
386
+ ### Full Workflow
387
+
388
+ ```bash
389
+ # 1. Consumer publishes contract
390
+ specshield contracts publish --file ./contracts/create-payment.json --org acme-store
563
391
 
564
- **Options:**
392
+ # 2. Provider verifies it
393
+ specshield contracts verify --contract-id 42 --base-url http://localhost:8080 --provider-version v2.1.0
565
394
 
566
- | Flag | Description |
567
- |---|---|
568
- | `--provider <key>` | Provider service key (required) |
569
- | `--version <ver>` | Provider version to check (required) |
570
- | `--env <environment>` | Target environment |
571
- | `--json` | Output raw JSON |
395
+ # 3. Gate the deployment
396
+ specshield contracts can-i-deploy --provider payment-service --version v2.1.0
397
+ ```
572
398
 
573
399
  ---
574
400
 
575
- ### Full Publish Verify → Deploy Workflow
401
+ ## CI/CD GitHub Actions
576
402
 
577
- ```bash
578
- # 1. Consumer team publishes a contract
579
- specshield contracts publish \
580
- --file ./contracts/create-payment.json \
581
- --org acme
403
+ ### On Pull Request — Catch breaking changes before merge
582
404
 
583
- # 2. Provider team starts their service locally
584
- ./gradlew bootRun &
405
+ ```yaml
406
+ name: API Contract Check
585
407
 
586
- # 3. Provider team verifies the contract
587
- specshield contracts verify \
588
- --contract-id 42 \
589
- --base-url http://localhost:8080 \
590
- --provider-version v2.1.0 \
591
- --env staging
408
+ on:
409
+ pull_request:
410
+ branches: [main]
592
411
 
593
- # 4. Gate the deployment
594
- specshield contracts can-i-deploy \
595
- --provider payment-service \
596
- --version v2.1.0 \
597
- --env staging
412
+ jobs:
413
+ check-api-contract:
414
+ runs-on: ubuntu-latest
415
+ steps:
416
+ - uses: actions/checkout@v4
417
+ with:
418
+ fetch-depth: 0
419
+ - uses: actions/setup-node@v4
420
+ with:
421
+ node-version: '20'
422
+ - run: npm install -g specshield
423
+ - name: Get base spec
424
+ run: git show origin/main:api/openapi.yaml > /tmp/base.yaml
425
+ - name: Compare specs
426
+ run: specshield compare /tmp/base.yaml api/openapi.yaml --fail-on-breaking
598
427
  ```
599
428
 
600
- ---
601
-
602
- ### Contracts in CI/CD
603
-
604
- #### GitHub Actions — Publish on consumer change
429
+ ### On Push — Publish consumer contract
605
430
 
606
431
  ```yaml
607
432
  name: Publish Contract
@@ -613,7 +438,7 @@ on:
613
438
  - 'contracts/**'
614
439
 
615
440
  jobs:
616
- publish-contract:
441
+ publish:
617
442
  runs-on: ubuntu-latest
618
443
  steps:
619
444
  - uses: actions/checkout@v4
@@ -627,11 +452,11 @@ jobs:
627
452
  run: |
628
453
  specshield contracts publish \
629
454
  --file ./contracts/create-payment.json \
630
- --org acme \
455
+ --org acme-store \
631
456
  --tag ${{ github.ref_name }}
632
457
  ```
633
458
 
634
- #### GitHub Actions — Verify + can-i-deploy on provider change
459
+ ### On Push — Verify provider + gate deployment
635
460
 
636
461
  ```yaml
637
462
  name: Contract Verification
@@ -641,30 +466,23 @@ on:
641
466
  branches: [main]
642
467
 
643
468
  jobs:
644
- verify-contracts:
469
+ verify:
645
470
  runs-on: ubuntu-latest
646
- services:
647
- payment-service:
648
- image: myorg/payment-service:${{ github.sha }}
649
- ports:
650
- - 8080:8080
651
471
  steps:
652
472
  - uses: actions/checkout@v4
653
473
  - uses: actions/setup-node@v4
654
474
  with:
655
475
  node-version: '20'
656
476
  - run: npm install -g specshield
657
-
658
477
  - name: Verify contract
659
478
  env:
660
479
  SPECSHIELD_API_KEY: ${{ secrets.SPECSHIELD_API_KEY }}
661
480
  run: |
662
481
  specshield contracts verify \
663
- --contract-id ${{ vars.PAYMENT_CONTRACT_ID }} \
482
+ --contract-id ${{ vars.CONTRACT_ID }} \
664
483
  --base-url http://localhost:8080 \
665
484
  --provider-version ${{ github.sha }} \
666
485
  --env staging
667
-
668
486
  - name: Can I deploy?
669
487
  env:
670
488
  SPECSHIELD_API_KEY: ${{ secrets.SPECSHIELD_API_KEY }}
@@ -679,22 +497,20 @@ jobs:
679
497
 
680
498
  ## Config File
681
499
 
682
- Create `.specshield.yml` in your project root to set default behavior:
500
+ Create `.specshield.yml` in your project root:
683
501
 
684
502
  ```yaml
685
503
  failOnBreaking: true
686
- allowBreakingChanges: false
687
504
  severity: error
688
505
 
689
506
  ignore:
690
507
  - "DELETE /admin removed"
691
- - "User.internal_id removed"
692
508
 
693
509
  remote:
694
510
  enabled: false
695
511
  url: "https://specshield.io/compare"
696
512
  timeout: 10000
697
- apiKey: "" # prefer env var or specshield login instead
513
+ # apiKey: "" use env var instead
698
514
  ```
699
515
 
700
516
  CLI flags always override config file values.
@@ -709,17 +525,16 @@ specshield compare <base> <target> [options]
709
525
 
710
526
  | Option | Description |
711
527
  |---|---|
712
- | `--remote` | Use the SpecShield hosted compare API |
713
- | `--api-key <key>` | API token for remote mode (overrides env and stored config) |
714
- | `--remote-url <url>` | Override the hosted API base URL |
715
- | `--fail-on-breaking` | Exit code 1 if breaking changes are found |
528
+ | `--remote` | Use the SpecShield hosted API |
529
+ | `--api-key <key>` | API token |
530
+ | `--fail-on-breaking` | Exit code 1 on breaking changes |
716
531
  | `--allow-breaking` | Override fail-on-breaking |
717
- | `--json` | Output machine-readable JSON |
718
- | `--output <file>` | Save result to a file |
719
- | `--ignore <change>` | Ignore a specific change string (repeatable) |
720
- | `--severity <level>` | Minimum severity: `info` / `warning` / `error` |
532
+ | `--json` | Machine-readable JSON output |
533
+ | `--output <file>` | Save result to file |
534
+ | `--ignore <change>` | Ignore a specific change (repeatable) |
535
+ | `--severity <level>` | `info` / `warning` / `error` |
721
536
  | `--config <path>` | Path to `.specshield.yml` |
722
- | `--timeout <ms>` | Request timeout for remote mode (default: 10000) |
537
+ | `--timeout <ms>` | Request timeout for remote mode |
723
538
 
724
539
  ---
725
540
 
@@ -727,79 +542,32 @@ specshield compare <base> <target> [options]
727
542
 
728
543
  | Code | Meaning |
729
544
  |---|---|
730
- | `0` | Success — no blocking issues |
731
- | `1` | Breaking changes found and `--fail-on-breaking` is active |
732
- | `2` | Invalid input, missing token, config error, or runtime error |
545
+ | `0` | Clean — no breaking changes |
546
+ | `1` | Breaking changes found with `--fail-on-breaking` |
547
+ | `2` | Config error, missing token, or runtime error |
733
548
 
734
549
  ---
735
550
 
736
- ## CI/CD — GitHub Actions
737
-
738
- ### Local compare (no token required)
739
-
740
- ```yaml
741
- name: API Contract Check
742
-
743
- on:
744
- pull_request:
745
- branches: [main]
746
-
747
- jobs:
748
- check-api-contract:
749
- runs-on: ubuntu-latest
750
- steps:
751
- - uses: actions/checkout@v4
752
- with:
753
- fetch-depth: 0
754
-
755
- - uses: actions/setup-node@v4
756
- with:
757
- node-version: '20'
758
-
759
- - run: npm install -g specshield
760
-
761
- - name: Get base spec from main branch
762
- run: git show origin/main:api/openapi.yaml > /tmp/base-spec.yaml
763
-
764
- - name: Compare specs
765
- run: |
766
- specshield compare /tmp/base-spec.yaml api/openapi.yaml \
767
- --fail-on-breaking \
768
- --output spec-diff.json
551
+ ## License
769
552
 
770
- - name: Upload diff report
771
- if: always()
772
- uses: actions/upload-artifact@v4
773
- with:
774
- name: spec-diff
775
- path: spec-diff.json
776
- ```
553
+ MIT © Deepak Satyam
777
554
 
778
- ### Remote compare (with SpecShield hosted API)
555
+ ---
779
556
 
780
- Add your API token as a GitHub Actions secret named `SPECSHIELD_API_KEY`, then:
557
+ ## Support
781
558
 
782
- ```yaml
783
- - name: Compare specs (remote)
784
- env:
785
- SPECSHIELD_API_KEY: ${{ secrets.SPECSHIELD_API_KEY }}
786
- run: |
787
- specshield compare /tmp/base-spec.yaml api/openapi.yaml \
788
- --remote \
789
- --fail-on-breaking \
790
- --output spec-diff.json
791
- ```
559
+ Questions or issues?
792
560
 
793
- > **Note:** If your project generates its OpenAPI spec dynamically (e.g. Spring Boot, FastAPI), add a build step before the compare step to generate the spec from your code.
561
+ - 📧 [admin@specshield.io](mailto:admin@specshield.io)
562
+ - 🐛 [Open an issue on GitHub](https://github.com/specshield26/specshield-cli/issues)
563
+ - 🌐 [specshield.io](https://specshield.io)
794
564
 
795
565
  ---
796
566
 
797
- ## License
567
+ <div align="center">
798
568
 
799
- MIT © Deepak Satyam
800
-
801
- ---
569
+ **[⭐ Star on GitHub](https://github.com/specshield26/specshield-cli) · [📦 View on npm](https://www.npmjs.com/package/specshield) · [🚀 Create free account](https://specshield.io)**
802
570
 
803
- ## Support
571
+ *Stop finding out about API breakage from your users.*
804
572
 
805
- Questions or issues? Reach out at [admin@specshield.io](mailto:admin@specshield.io) or open an issue on GitHub.
573
+ </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specshield",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "CLI to compare OpenAPI/Swagger specs and detect breaking changes for CI/CD pipelines and local developer workflows.",
5
5
  "main": "src/cli.js",
6
6
  "bin": {
@@ -13,29 +13,37 @@
13
13
  "lint": "eslint src tests --ext .js"
14
14
  },
15
15
  "keywords": [
16
- "openapi",
17
- "swagger",
18
- "openapi-diff",
19
- "swagger-diff",
20
- "api-diff",
21
- "api-breaking-changes",
22
- "breaking-change-detection",
23
- "contract-testing",
24
- "api-contract",
25
- "api-versioning",
26
- "api-governance",
27
- "ci-cd",
28
- "devops",
29
- "github-actions",
30
- "automation",
31
- "cli",
32
- "developer-tools",
33
- "yaml",
34
- "json",
35
- "schema-diff",
36
- "rest-api",
37
- "openapi-cli"
38
- ],
16
+ "openapi",
17
+ "swagger",
18
+ "api-diff",
19
+ "openapi-diff",
20
+ "swagger-diff",
21
+ "api-diff-tool",
22
+ "breaking-change-detection",
23
+ "api-breaking-changes",
24
+ "prevent-breaking-api",
25
+ "api-regression",
26
+ "api-compatibility",
27
+ "contract-testing",
28
+ "consumer-driven-contract",
29
+ "api-contract",
30
+ "contract-verification",
31
+ "can-i-deploy",
32
+ "ci-cd",
33
+ "devops",
34
+ "github-actions",
35
+ "cli",
36
+ "developer-tools",
37
+ "openapi-compare",
38
+ "swagger-compare",
39
+ "pact-alternative",
40
+ "api-contract-testing",
41
+ "microservices",
42
+ "api-quality",
43
+ "api-governance",
44
+ "yaml",
45
+ "json"
46
+ ],
39
47
  "license": "MIT",
40
48
  "files": [
41
49
  "bin",