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