postman-cli 1.62.0 → 1.65.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/bin/postman.js +19 -0
- package/man/postman.1 +409 -13
- package/package.json +11 -7
- package/scripts/post-npm-installation.js +402 -0
package/README.md
CHANGED
|
@@ -20,6 +20,18 @@ The Postman CLI brings the power of Postman’s API platform directly to your te
|
|
|
20
20
|
npm install -g postman-cli
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
After a global npm installation, the package checks for existing Claude Code and Codex
|
|
24
|
+
configuration directories. When found, it adds a managed Postman CLI availability note to
|
|
25
|
+
the agent's global instructions without replacing existing content. This step is idempotent
|
|
26
|
+
and non-blocking, so an inaccessible agent configuration does not fail the CLI installation.
|
|
27
|
+
|
|
28
|
+
npm hides successful lifecycle-script output by default. To see the agent configuration
|
|
29
|
+
summary and Claude Code plugin recommendation during installation, use:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install -g postman-cli --foreground-scripts
|
|
33
|
+
```
|
|
34
|
+
|
|
23
35
|
### Alternative Installation Methods
|
|
24
36
|
|
|
25
37
|
For direct binary downloads, platform-specific installers, or other installation methods, see the **[Installation Guide](https://learning.postman.com/docs/postman-cli/postman-cli-installation/)**.
|
package/bin/postman.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
const { constants } = require('os');
|
|
4
|
+
|
|
3
5
|
// Keep this wrapper alive while the native binary handles shutdown gracefully.
|
|
4
6
|
process.on('SIGINT', function () {});
|
|
5
7
|
process.on('SIGTERM', function () {});
|
|
@@ -10,5 +12,22 @@ try {
|
|
|
10
12
|
run(...process.argv.slice(2));
|
|
11
13
|
}
|
|
12
14
|
catch (error) {
|
|
15
|
+
// The CLI's exit codes are a documented contract (`postman init` returns 2 for
|
|
16
|
+
// ambiguous specs and 4 for a refusal, for instance), so the binary's own code has
|
|
17
|
+
// to survive this wrapper. execFileSync throws on any non-zero exit and carries
|
|
18
|
+
// the code as `status`; collapsing that to 1 made a recoverable refusal
|
|
19
|
+
// indistinguishable from a crash.
|
|
20
|
+
if (typeof error.status === 'number') {
|
|
21
|
+
process.exit(error.status);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// A signalled child has no status. Report it the way a shell does.
|
|
25
|
+
if (error.signal) {
|
|
26
|
+
process.exit(128 + (constants.signals[error.signal] || 0));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Spawning the binary failed outright (missing platform package, not executable).
|
|
30
|
+
// The message never reached the user before, leaving a silent exit 1.
|
|
31
|
+
process.stderr.write(`${error.message || error}\n`);
|
|
13
32
|
process.exit(1);
|
|
14
33
|
}
|
package/man/postman.1
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.TH POSTMAN 1 "2026-09-
|
|
1
|
+
.TH POSTMAN 1 "2026-09-25" "v1.65.0" "Postman CLI Manual"
|
|
2
2
|
.SH NAME
|
|
3
3
|
postman \- Command\-line companion utility for Postman
|
|
4
4
|
.SH SYNOPSIS
|
|
@@ -94,7 +94,7 @@ Use the skills bundled with this CLI instead of fetching the latest
|
|
|
94
94
|
Which spec is authoritative, when more than one could be
|
|
95
95
|
.TP
|
|
96
96
|
.B \-\-visibility <status>
|
|
97
|
-
Create and bind a workspace non\-interactively (personal
|
|
97
|
+
Create and bind a workspace non\-interactively (personal, team)
|
|
98
98
|
.TP
|
|
99
99
|
.B \-\-no\-cloud
|
|
100
100
|
Skip the workspace step entirely
|
|
@@ -120,11 +120,21 @@ Exit codes:
|
|
|
120
120
|
|
|
121
121
|
Code 5 needs \-\-visibility: without it no workspace was requested, so nothing
|
|
122
122
|
can fail for not getting one. It does not mean re\-run init \- the local files
|
|
123
|
-
are already written.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
123
|
+
are already written. A \-\-visibility that is not personal, team is code 5 on
|
|
124
|
+
every path, including \-\-json, CI and \-\-no\-cloud: none of them makes the value
|
|
125
|
+
usable, so none of them should report success for it.
|
|
126
|
+
|
|
127
|
+
Under \-\-json, read `exitCode`, `refusal`, `usageError` and `cloud` from the
|
|
128
|
+
payload rather than matching the messages on stderr. `refusal.kind` is one of
|
|
129
|
+
foreign\-postman\-dir, bound\-spec\-missing, spec\-hint\-unmatched. `usageError`
|
|
130
|
+
names the flag whose value init could not use. `cloud` says what happened to
|
|
131
|
+
the workspace step, including why it was skipped.
|
|
132
|
+
|
|
133
|
+
\-\-json with \-\-visibility creates the workspace, same as without it: stdout
|
|
134
|
+
carries the payload and everything meant for a person goes to stderr. It used
|
|
135
|
+
to skip the step and exit 0, so a missing `origin` remote or a failed bind
|
|
136
|
+
went unreported. Without \-\-visibility, \-\-json still skips \- there is nothing
|
|
137
|
+
to create and init may not prompt.
|
|
128
138
|
|
|
129
139
|
Examples:
|
|
130
140
|
$ postman init
|
|
@@ -283,9 +293,18 @@ Score a Postman collection for AI readiness by ID, local file path, or local\-mo
|
|
|
283
293
|
.B collection get
|
|
284
294
|
Fetch a Postman collection in the V3 format and print it.
|
|
285
295
|
.TP
|
|
296
|
+
.B collection generate
|
|
297
|
+
Generate artifacts from a collection.
|
|
298
|
+
.TP
|
|
299
|
+
.B collection sync
|
|
300
|
+
Sync artifacts generated from a collection.
|
|
301
|
+
.TP
|
|
286
302
|
.B collection request
|
|
287
303
|
Add, update, or remove requests in a local v3 collection.
|
|
288
304
|
.TP
|
|
305
|
+
.B collection folder
|
|
306
|
+
Add, update, or remove folders in a local v3 collection.
|
|
307
|
+
.TP
|
|
289
308
|
.B collection list
|
|
290
309
|
List collections: your local project's collections by default, or a Postman cloud workspace's collections with \-\-workspace.
|
|
291
310
|
.TP
|
|
@@ -363,6 +382,9 @@ Score a Postman collection for AI readiness by ID, local file path, or local\-mo
|
|
|
363
382
|
.B \-o, \-\-output <value>
|
|
364
383
|
Output format for the results. [choices: "cli", "json", "html"]
|
|
365
384
|
.TP
|
|
385
|
+
.B \-\-export <path>
|
|
386
|
+
Write the report to this file instead of stdout. A directory receives the report under a name derived from the collection. Requires \-\-output html.
|
|
387
|
+
.TP
|
|
366
388
|
.B \-\-min\-score <n>
|
|
367
389
|
Exit with a non\-zero code if the overall score is below this threshold (0\-100).
|
|
368
390
|
|
|
@@ -372,6 +394,7 @@ Examples:
|
|
|
372
394
|
$ postman collection ai\-readiness ./postman/collections/My\e API
|
|
373
395
|
$ postman collection ai\-readiness ./my\-collection.json
|
|
374
396
|
$ postman collection ai\-readiness 631643\-f695cab7\-... \-\-output json
|
|
397
|
+
$ postman collection ai\-readiness ./my\-collection.json \-\-output html > report.html
|
|
375
398
|
$ postman collection ai\-readiness ./my\-collection.json \-\-min\-score 70
|
|
376
399
|
|
|
377
400
|
Resolving a collection by ID requires authentication. Use `postman login` before running this command with a UID.
|
|
@@ -397,6 +420,80 @@ Eg. postman collection get 12345\-33823532ab9e41c9b6fd12d0fd459b8b
|
|
|
397
420
|
postman collection get 0123456789abcdef01234567 \-\-json
|
|
398
421
|
|
|
399
422
|
|
|
423
|
+
.SS "collection generate"
|
|
424
|
+
Generate artifacts from a collection.
|
|
425
|
+
|
|
426
|
+
.B Usage:
|
|
427
|
+
[options] [command]
|
|
428
|
+
|
|
429
|
+
.B Subcommands:
|
|
430
|
+
.TP
|
|
431
|
+
.B collection generate spec
|
|
432
|
+
Generate an OpenAPI specification from a Postman collection.
|
|
433
|
+
|
|
434
|
+
.SS "collection generate spec"
|
|
435
|
+
Generate an OpenAPI specification from a Postman collection.
|
|
436
|
+
|
|
437
|
+
.B Usage:
|
|
438
|
+
[options] <collection>
|
|
439
|
+
|
|
440
|
+
.B Options:
|
|
441
|
+
.TP
|
|
442
|
+
.B \-n, \-\-name <name>
|
|
443
|
+
Specification name / title
|
|
444
|
+
.TP
|
|
445
|
+
.B \-\-spec\-version <ver>
|
|
446
|
+
Target OpenAPI version: 3.1, 3.0, or 2.0 (default: 3.1) (default: 3.1)
|
|
447
|
+
.TP
|
|
448
|
+
.B \-f, \-\-format <fmt>
|
|
449
|
+
Output format: yaml or json (default: yaml) (default: yaml)
|
|
450
|
+
.TP
|
|
451
|
+
.B \-\-api\-key <key>
|
|
452
|
+
Postman API key
|
|
453
|
+
|
|
454
|
+
.TP Examples:
|
|
455
|
+
|
|
456
|
+
Examples:
|
|
457
|
+
postman collection generate spec ./postman/collections/My\e API \-n "My API Spec"
|
|
458
|
+
postman collection generate spec ./postman/collections/My\e API \-n "My Spec" \-\-spec\-version 3.0
|
|
459
|
+
postman collection generate spec ./collection.json \-n "My Spec" \-f json
|
|
460
|
+
postman collection generate spec 12345678\-abcd\-1234\-abcd\-1234567890ab \-n "My Spec"
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
.SS "collection sync"
|
|
465
|
+
Sync artifacts generated from a collection.
|
|
466
|
+
|
|
467
|
+
.B Usage:
|
|
468
|
+
[options] [command]
|
|
469
|
+
|
|
470
|
+
.B Subcommands:
|
|
471
|
+
.TP
|
|
472
|
+
.B collection sync spec
|
|
473
|
+
Sync a specification from a linked collection (local path or cloud UUID).
|
|
474
|
+
|
|
475
|
+
.SS "collection sync spec"
|
|
476
|
+
Sync a specification from a linked collection (local path or cloud UUID).
|
|
477
|
+
|
|
478
|
+
.B Usage:
|
|
479
|
+
[options] <collection>
|
|
480
|
+
|
|
481
|
+
.B Options:
|
|
482
|
+
.TP
|
|
483
|
+
.B \-\-spec\-id <id>
|
|
484
|
+
Specification ID to sync (required for cloud mode)
|
|
485
|
+
.TP
|
|
486
|
+
.B \-\-api\-key <key>
|
|
487
|
+
Postman API key
|
|
488
|
+
|
|
489
|
+
.TP Examples:
|
|
490
|
+
|
|
491
|
+
Examples:
|
|
492
|
+
postman collection sync spec ./postman/collections/My\e API
|
|
493
|
+
postman collection sync spec 12345\-col\-id \-\-spec\-id 67890\-spec\-id
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
|
|
400
497
|
.SS "collection request"
|
|
401
498
|
Add, update, or remove requests in a local v3 collection.
|
|
402
499
|
|
|
@@ -547,6 +644,132 @@ Examples:
|
|
|
547
644
|
|
|
548
645
|
|
|
549
646
|
|
|
647
|
+
.SS "collection folder"
|
|
648
|
+
Add, update, or remove folders in a local v3 collection.
|
|
649
|
+
|
|
650
|
+
.B Usage:
|
|
651
|
+
[options] [command]
|
|
652
|
+
|
|
653
|
+
.B Subcommands:
|
|
654
|
+
.TP
|
|
655
|
+
.B collection folder add
|
|
656
|
+
Add an empty folder to a local v3 collection (set its details later with `update`).
|
|
657
|
+
.TP
|
|
658
|
+
.B collection folder update
|
|
659
|
+
Update a folder in a v3 collection (only the fields you pass).
|
|
660
|
+
.TP
|
|
661
|
+
.B collection folder rm
|
|
662
|
+
Remove a folder from a v3 collection (recursive: removes everything inside it).
|
|
663
|
+
|
|
664
|
+
.SS "collection folder add"
|
|
665
|
+
Add an empty folder to a local v3 collection (set its details later with `update`).
|
|
666
|
+
|
|
667
|
+
.B Usage:
|
|
668
|
+
[options] [folder\-name]
|
|
669
|
+
|
|
670
|
+
.B Options:
|
|
671
|
+
.TP
|
|
672
|
+
.B \-\-collection <id|name>
|
|
673
|
+
Target collection: name, directory, id, cloud id, or path. Required.
|
|
674
|
+
.TP
|
|
675
|
+
.B \-\-folder <id|name|path>
|
|
676
|
+
Parent folder within the collection, e.g. "Users/Admin". Defaults to the root.
|
|
677
|
+
.TP
|
|
678
|
+
.B \-w, \-\-workspace <id>
|
|
679
|
+
Target a Postman cloud workspace by id (cloud mode).
|
|
680
|
+
.TP
|
|
681
|
+
.B \-\-json
|
|
682
|
+
JSON output.
|
|
683
|
+
|
|
684
|
+
.TP Examples:
|
|
685
|
+
|
|
686
|
+
Creates an empty folder (name only); set its description with `collection folder update`. Nest it with \-\-folder.
|
|
687
|
+
|
|
688
|
+
Examples:
|
|
689
|
+
postman collection folder add Users \-\-collection "My API"
|
|
690
|
+
postman collection folder add \-\-collection "My API" # named "New folder"
|
|
691
|
+
postman collection folder add Admin \-\-collection "My API" \-\-folder Users
|
|
692
|
+
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
.SS "collection folder update"
|
|
696
|
+
Update a folder in a v3 collection (only the fields you pass).
|
|
697
|
+
|
|
698
|
+
.B Usage:
|
|
699
|
+
[options] <folder>
|
|
700
|
+
|
|
701
|
+
.B Options:
|
|
702
|
+
.TP
|
|
703
|
+
.B \-\-collection <id|name>
|
|
704
|
+
Target collection: name, directory, id, cloud id, or path (cloud: id only). Required.
|
|
705
|
+
.TP
|
|
706
|
+
.B \-\-folder <id|name|path>
|
|
707
|
+
Parent folder to scope the selector, e.g. "Users" (local: name/path; cloud: id).
|
|
708
|
+
.TP
|
|
709
|
+
.B \-\-name <name>
|
|
710
|
+
Rename the folder (moves its directory).
|
|
711
|
+
.TP
|
|
712
|
+
.B \-\-description <text>
|
|
713
|
+
Folder description.
|
|
714
|
+
.TP
|
|
715
|
+
.B \-\-auth <spec>
|
|
716
|
+
Folder auth: none, inherit, bearer:TOKEN, basic:USER:PASS, apikey:KEY:VALUE[:header|query], oauth2:TOKEN.
|
|
717
|
+
.TP
|
|
718
|
+
.B \-\-scripts <event:script>
|
|
719
|
+
Replace folder scripts. event is prerequest or test; script is @file, \- for stdin, or inline. Repeatable. (default: )
|
|
720
|
+
.TP
|
|
721
|
+
.B \-w, \-\-workspace <id>
|
|
722
|
+
Target a Postman cloud workspace by id (cloud mode).
|
|
723
|
+
.TP
|
|
724
|
+
.B \-\-json
|
|
725
|
+
JSON output.
|
|
726
|
+
|
|
727
|
+
.TP Examples:
|
|
728
|
+
|
|
729
|
+
Select the folder by the <folder> selector: local — a name or "Parent/Name" path (or \-\-folder to scope a bare name); cloud (\-\-workspace) — a folder id, with \-\-collection an id too.
|
|
730
|
+
|
|
731
|
+
Examples:
|
|
732
|
+
postman collection folder update Users \-\-collection "My API" \-\-name Accounts
|
|
733
|
+
postman collection folder update "Users/Admin" \-\-collection "My API" \-\-description "Admin endpoints"
|
|
734
|
+
postman collection folder update Admin \-\-collection "My API" \-\-folder Users \-\-auth bearer:TOKEN
|
|
735
|
+
postman collection folder update <folderId> \-\-collection <collectionId> \-\-name Accounts \-w <workspaceId>
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
.SS "collection folder rm"
|
|
740
|
+
Remove a folder from a v3 collection (recursive: removes everything inside it).
|
|
741
|
+
|
|
742
|
+
.B Usage:
|
|
743
|
+
[options] <folder>
|
|
744
|
+
|
|
745
|
+
.B Options:
|
|
746
|
+
.TP
|
|
747
|
+
.B \-\-collection <id|name>
|
|
748
|
+
Target collection: name, directory, id, cloud id, or path (cloud: id only). Required.
|
|
749
|
+
.TP
|
|
750
|
+
.B \-\-folder <id|name|path>
|
|
751
|
+
Parent folder to scope the selector, e.g. "Users" (local: name/path; cloud: id).
|
|
752
|
+
.TP
|
|
753
|
+
.B \-y, \-\-yes
|
|
754
|
+
Skip the confirmation prompt (required when stdout is not a TTY).
|
|
755
|
+
.TP
|
|
756
|
+
.B \-w, \-\-workspace <id>
|
|
757
|
+
Target a Postman cloud workspace by id (cloud mode).
|
|
758
|
+
.TP
|
|
759
|
+
.B \-\-json
|
|
760
|
+
JSON output.
|
|
761
|
+
|
|
762
|
+
.TP Examples:
|
|
763
|
+
|
|
764
|
+
Removal is recursive. Select the folder by the <folder> selector: local — a name or "Parent/Name" path (or \-\-folder to scope a bare name); cloud (\-\-workspace) — a folder id, with \-\-collection an id too.
|
|
765
|
+
|
|
766
|
+
Examples:
|
|
767
|
+
postman collection folder rm Users \-\-collection "My API" \-\-yes
|
|
768
|
+
postman collection folder rm "Users/Admin" \-\-collection "My API" \-y
|
|
769
|
+
postman collection folder rm <folderId> \-\-collection <collectionId> \-y \-w <workspaceId>
|
|
770
|
+
|
|
771
|
+
|
|
772
|
+
|
|
550
773
|
.SS "collection list"
|
|
551
774
|
List collections: your local project's collections by default, or a Postman cloud workspace's collections with \-\-workspace.
|
|
552
775
|
|
|
@@ -733,6 +956,15 @@ Redirect requests for a URL or {{variable}} to a mock during the run. Format: "<
|
|
|
733
956
|
.B \-\-simulate <path>
|
|
734
957
|
Start mock servers with fault\-injection scenarios from a .sim.yaml file
|
|
735
958
|
.TP
|
|
959
|
+
.B \-\-simulation <id>
|
|
960
|
+
Simulation id to record start history against when using \-\-simulate.
|
|
961
|
+
.TP
|
|
962
|
+
.B \-\-simulate\-workspace <id>
|
|
963
|
+
Workspace that owns the \-\-simulate run, for recording its start history.
|
|
964
|
+
.TP
|
|
965
|
+
.B \-\-no\-simulate\-history
|
|
966
|
+
Do not record the \-\-simulate run in the simulation's start history.
|
|
967
|
+
.TP
|
|
736
968
|
.B \-\-report\-events
|
|
737
969
|
Upload results for git\-native v3 collection runs. Analytics are sent by default
|
|
738
970
|
.TP
|
|
@@ -1211,6 +1443,9 @@ Create a new spec in a workspace, or (with path) scaffold a local spec file.
|
|
|
1211
1443
|
.TP
|
|
1212
1444
|
.B spec generate
|
|
1213
1445
|
Generate artifacts from a specification.
|
|
1446
|
+
.TP
|
|
1447
|
+
.B spec sync
|
|
1448
|
+
Sync a generated collection with its source specification.
|
|
1214
1449
|
|
|
1215
1450
|
.SS "spec lint"
|
|
1216
1451
|
Run linting on the given specification by ID or local file path.
|
|
@@ -1248,6 +1483,9 @@ Score an OpenAPI specification for AI readiness by ID or local file path.
|
|
|
1248
1483
|
.B \-o, \-\-output <value>
|
|
1249
1484
|
Output format for the results. [choices: "cli", "json", "html"]
|
|
1250
1485
|
.TP
|
|
1486
|
+
.B \-\-export <path>
|
|
1487
|
+
Write the report to this file instead of stdout. A directory receives the report under a name derived from the specification. Requires \-\-output html.
|
|
1488
|
+
.TP
|
|
1251
1489
|
.B \-\-min\-score <n>
|
|
1252
1490
|
Exit with a non\-zero code if the overall score is below this threshold (0\-100).
|
|
1253
1491
|
|
|
@@ -1256,6 +1494,8 @@ Exit with a non\-zero code if the overall score is below this threshold (0\-100)
|
|
|
1256
1494
|
Examples:
|
|
1257
1495
|
$ postman spec ai\-readiness ./openapi.yaml
|
|
1258
1496
|
$ postman spec ai\-readiness 6e2e5b3e\-... \-\-output json
|
|
1497
|
+
$ postman spec ai\-readiness ./openapi.yaml \-\-output html > report.html
|
|
1498
|
+
$ postman spec ai\-readiness ./openapi.yaml \-\-output html \-\-export ./report.html
|
|
1259
1499
|
$ postman spec ai\-readiness ./openapi.yaml \-\-min\-score 70
|
|
1260
1500
|
|
|
1261
1501
|
|
|
@@ -1478,6 +1718,39 @@ Examples:
|
|
|
1478
1718
|
|
|
1479
1719
|
|
|
1480
1720
|
|
|
1721
|
+
.SS "spec sync"
|
|
1722
|
+
Sync a generated collection with its source specification.
|
|
1723
|
+
|
|
1724
|
+
.B Usage:
|
|
1725
|
+
[options] [command]
|
|
1726
|
+
|
|
1727
|
+
.B Subcommands:
|
|
1728
|
+
.TP
|
|
1729
|
+
.B spec sync collection
|
|
1730
|
+
Sync a collection from a linked specification (local path or cloud UUID).
|
|
1731
|
+
|
|
1732
|
+
.SS "spec sync collection"
|
|
1733
|
+
Sync a collection from a linked specification (local path or cloud UUID).
|
|
1734
|
+
|
|
1735
|
+
.B Usage:
|
|
1736
|
+
[options] <spec>
|
|
1737
|
+
|
|
1738
|
+
.B Options:
|
|
1739
|
+
.TP
|
|
1740
|
+
.B \-\-collection\-id <id>
|
|
1741
|
+
Collection ID to sync (required for cloud mode)
|
|
1742
|
+
.TP
|
|
1743
|
+
.B \-\-api\-key <key>
|
|
1744
|
+
Postman API key
|
|
1745
|
+
|
|
1746
|
+
.TP Examples:
|
|
1747
|
+
|
|
1748
|
+
Examples:
|
|
1749
|
+
postman spec sync collection ./postman/specs/My\e API/index.yaml
|
|
1750
|
+
postman spec sync collection 12345\-spec\-id \-\-collection\-id 67890\-col\-id
|
|
1751
|
+
|
|
1752
|
+
|
|
1753
|
+
|
|
1481
1754
|
.SS "monitor"
|
|
1482
1755
|
Run and manage Postman monitors.
|
|
1483
1756
|
|
|
@@ -2000,12 +2273,18 @@ Read a workspace's metadata, and optionally the ids of what it holds.
|
|
|
2000
2273
|
.B workspace create
|
|
2001
2274
|
Create a Postman workspace and bind it to this git repository.
|
|
2002
2275
|
.TP
|
|
2276
|
+
.B workspace delete
|
|
2277
|
+
Permanently delete a workspace and everything in it. Prompts for confirmation unless \-\-yes is passed.
|
|
2278
|
+
.TP
|
|
2003
2279
|
.B workspace pull
|
|
2004
2280
|
Pull workspace entities from a Postman workspace into the local git\-native folder.
|
|
2005
2281
|
.TP
|
|
2006
2282
|
.B workspace connect-git
|
|
2007
2283
|
Connect a Postman workspace to a local git repository.
|
|
2008
2284
|
.TP
|
|
2285
|
+
.B workspace disconnect-git
|
|
2286
|
+
Disconnect a Postman workspace from its local git repository.
|
|
2287
|
+
.TP
|
|
2009
2288
|
.B workspace diff
|
|
2010
2289
|
Preview local\-vs\-cloud drift before pushing. Read\-only: nothing is created, updated or deleted.
|
|
2011
2290
|
|
|
@@ -2164,7 +2443,8 @@ Create even when a workspace is already recorded for this repo
|
|
|
2164
2443
|
|
|
2165
2444
|
.TP Examples:
|
|
2166
2445
|
|
|
2167
|
-
Requires a login (`postman login`) or POSTMAN_API_KEY.
|
|
2446
|
+
Requires a login (`postman login`) or POSTMAN_API_KEY. A guest session
|
|
2447
|
+
has no account to own a workspace: run `postman signup` first.
|
|
2168
2448
|
Refuses to run on CI: create once locally and commit the binding.
|
|
2169
2449
|
|
|
2170
2450
|
Examples:
|
|
@@ -2175,6 +2455,38 @@ Examples:
|
|
|
2175
2455
|
$ postman workspace create \-\-visibility personal \-\-no\-connect
|
|
2176
2456
|
|
|
2177
2457
|
|
|
2458
|
+
.SS "workspace delete"
|
|
2459
|
+
Permanently delete a workspace and everything in it. Prompts for confirmation unless \-\-yes is passed.
|
|
2460
|
+
|
|
2461
|
+
.B Usage:
|
|
2462
|
+
[options] [workspaceId]
|
|
2463
|
+
|
|
2464
|
+
.B Options:
|
|
2465
|
+
.TP
|
|
2466
|
+
.B \-y, \-\-yes
|
|
2467
|
+
Skip the confirmation prompt
|
|
2468
|
+
.TP
|
|
2469
|
+
.B \-\-json
|
|
2470
|
+
Print the outcome as machine\-readable JSON
|
|
2471
|
+
.TP
|
|
2472
|
+
.B \-\-verbose
|
|
2473
|
+
Show detailed logging
|
|
2474
|
+
.TP
|
|
2475
|
+
.B \-\-timeout <ms>
|
|
2476
|
+
Abort the run after this many milliseconds. Defaults to 30000.
|
|
2477
|
+
|
|
2478
|
+
.TP Examples:
|
|
2479
|
+
|
|
2480
|
+
Examples:
|
|
2481
|
+
postman workspace delete 12345678\-90ab\-cdef\-1234\-567890abcdef
|
|
2482
|
+
Confirm, then delete
|
|
2483
|
+
postman workspace delete 12345678\-90ab\-cdef\-1234\-567890abcdef \-\-yes
|
|
2484
|
+
Delete without confirmation (for scripts and CI)
|
|
2485
|
+
postman workspace delete 12345678\-90ab\-cdef\-1234\-567890abcdef \-\-yes \-\-json
|
|
2486
|
+
Machine\-readable outcome
|
|
2487
|
+
|
|
2488
|
+
|
|
2489
|
+
|
|
2178
2490
|
.SS "workspace pull"
|
|
2179
2491
|
Pull workspace entities from a Postman workspace into the local git\-native folder.
|
|
2180
2492
|
|
|
@@ -2228,6 +2540,36 @@ Examples:
|
|
|
2228
2540
|
|
|
2229
2541
|
|
|
2230
2542
|
|
|
2543
|
+
.SS "workspace disconnect\-git"
|
|
2544
|
+
Disconnect a Postman workspace from its local git repository.
|
|
2545
|
+
|
|
2546
|
+
.B Usage:
|
|
2547
|
+
[options] [workspaceId]
|
|
2548
|
+
|
|
2549
|
+
.B Options:
|
|
2550
|
+
.TP
|
|
2551
|
+
.B \-y, \-\-yes
|
|
2552
|
+
Skip all confirmation prompts
|
|
2553
|
+
.TP
|
|
2554
|
+
.B \-\-verbose
|
|
2555
|
+
Show detailed logging
|
|
2556
|
+
|
|
2557
|
+
.TP Examples:
|
|
2558
|
+
|
|
2559
|
+
Examples:
|
|
2560
|
+
postman workspace disconnect\-git
|
|
2561
|
+
Disconnect the workspace this folder is connected to. Disconnects it in
|
|
2562
|
+
Postman and clears the connection in .postman/resources.yaml. No files
|
|
2563
|
+
are deleted.
|
|
2564
|
+
postman workspace disconnect\-git <workspaceId>
|
|
2565
|
+
Disconnect a specific workspace, whatever workspace this folder is
|
|
2566
|
+
connected to. Use this to clear an existing workspace connection. No files
|
|
2567
|
+
are deleted.
|
|
2568
|
+
postman workspace disconnect\-git \-\-yes
|
|
2569
|
+
CI: skip the confirmation prompt.
|
|
2570
|
+
|
|
2571
|
+
|
|
2572
|
+
|
|
2231
2573
|
.SS "workspace diff"
|
|
2232
2574
|
Preview local\-vs\-cloud drift before pushing. Read\-only: nothing is created, updated or deleted.
|
|
2233
2575
|
|
|
@@ -2246,7 +2588,7 @@ Skip content comparison. Faster, but updates are listed without checking whether
|
|
|
2246
2588
|
Print the diff as machine\-readable JSON.
|
|
2247
2589
|
.TP
|
|
2248
2590
|
.B \-\-exit\-code
|
|
2249
|
-
Exit with code 1 when
|
|
2591
|
+
Exit with code 1 when a verified difference is found (for CI gates). Entity types with no comparison path are reported but do not fail the gate.
|
|
2250
2592
|
.TP
|
|
2251
2593
|
.B \-\-verbose
|
|
2252
2594
|
Show detailed logging
|
|
@@ -2349,10 +2691,10 @@ Specify an Id to a Postman Environment
|
|
|
2349
2691
|
Specify an Id to a Postman Globals
|
|
2350
2692
|
.TP
|
|
2351
2693
|
.B \-\-setup\-collection <id>
|
|
2352
|
-
Collection UID to run before the
|
|
2694
|
+
Collection UID to run before the performance test
|
|
2353
2695
|
.TP
|
|
2354
2696
|
.B \-\-teardown\-collection <id>
|
|
2355
|
-
Collection UID to run after the
|
|
2697
|
+
Collection UID to run after the performance test
|
|
2356
2698
|
.TP
|
|
2357
2699
|
.B \-\-vu\-count <count>
|
|
2358
2700
|
Number of virtual users (default: 20)
|
|
@@ -2366,6 +2708,24 @@ Load profile type: fixed, ramp\-up, spike, peak (default: ramp\-up)
|
|
|
2366
2708
|
.B \-\-data\-file <path>
|
|
2367
2709
|
Path to a JSON or CSV data file to use with the collection
|
|
2368
2710
|
.TP
|
|
2711
|
+
.B \-\-ssl\-client\-cert\-list <path>
|
|
2712
|
+
Path to a client certificates configuration file (JSON). Local runner only.
|
|
2713
|
+
.TP
|
|
2714
|
+
.B \-\-ssl\-client\-cert <path>
|
|
2715
|
+
Path to a client certificate (PEM) for mTLS targets. Local runner only.
|
|
2716
|
+
.TP
|
|
2717
|
+
.B \-\-ssl\-client\-key <path>
|
|
2718
|
+
Path to the client certificate private key. Local runner only.
|
|
2719
|
+
.TP
|
|
2720
|
+
.B \-\-ssl\-client\-passphrase <passphrase>
|
|
2721
|
+
Client certificate passphrase (for a protected key). Local runner only.
|
|
2722
|
+
.TP
|
|
2723
|
+
.B \-k, \-\-insecure
|
|
2724
|
+
Disable SSL certificate verification for the target. Local runner only.
|
|
2725
|
+
.TP
|
|
2726
|
+
.B \-\-ssl\-extra\-ca\-certs <path>
|
|
2727
|
+
Path to additionally trusted CA certificates (PEM) for the target. Local runner only.
|
|
2728
|
+
.TP
|
|
2369
2729
|
.B \-\-dataset\-id <id>
|
|
2370
2730
|
Use a Postman Dataset as iteration data (with \-\-dataset\-view\-id)
|
|
2371
2731
|
.TP
|
|
@@ -2399,6 +2759,7 @@ Format: "<{{var}}|host> mock|mock\-server:<path|id> [scenario]" (default: )
|
|
|
2399
2759
|
Examples:
|
|
2400
2760
|
postman performance run 123456\-45159473\-1e45\-1f34\-5678\-1234567890ab \-\-vu\-count 50 \-\-duration 15
|
|
2401
2761
|
postman performance run 123456\-45159473\-1e45\-1f34\-5678\-1234567890ab \-\-pass\-if "less_than(p95, 500)"
|
|
2762
|
+
postman performance run 123456\-45159473\-1e45\-1f34\-5678\-1234567890ab \-\-runner local \-\-setup\-collection 123456\-11111111\-1111\-4111\-8111\-111111111111 \-\-teardown\-collection 123456\-22222222\-2222\-4222\-8222\-222222222222
|
|
2402
2763
|
postman performance run 123456\-45159473\-1e45\-1f34\-5678\-1234567890ab \-\-runner postman\-cloud \-\-setup\-collection 123456\-11111111\-1111\-4111\-8111\-111111111111 \-\-teardown\-collection 123456\-22222222\-2222\-4222\-8222\-222222222222
|
|
2403
2764
|
postman performance run 123456\-45159473\-1e45\-1f34\-5678\-1234567890ab \-\-runner postman\-cloud\-static\-ip
|
|
2404
2765
|
|
|
@@ -3563,7 +3924,7 @@ Start a mock using its path if it lives in your repository, or its id if it live
|
|
|
3563
3924
|
.B Options:
|
|
3564
3925
|
.TP
|
|
3565
3926
|
.B \-e, \-\-environment <path>
|
|
3566
|
-
Path to a file of environment variables for the mock. Relative or absolute, e.g. ./postman/environments/dev.
|
|
3927
|
+
Path to a file of environment variables for the mock. Relative or absolute, e.g. ./postman/environments/dev.environment.yaml
|
|
3567
3928
|
.TP
|
|
3568
3929
|
.B \-g, \-\-globals <path>
|
|
3569
3930
|
Path to a file of global variables for the mock. Relative or absolute, e.g. ./globals.json
|
|
@@ -3573,14 +3934,27 @@ Port to run on (e.g. 4010), or "auto" for a free one. Defaults to the mock's con
|
|
|
3573
3934
|
.TP
|
|
3574
3935
|
.B \-\-api\-key <key>
|
|
3575
3936
|
Postman API key, used with a Postman cloud id (defaults to your `postman login` session)
|
|
3937
|
+
.TP
|
|
3938
|
+
.B \-w, \-\-workspace <id>
|
|
3939
|
+
Workspace that owns the run, for recording its start history. Auto\-resolved for a Postman cloud id; required to record history for a path.
|
|
3940
|
+
.TP
|
|
3941
|
+
.B \-\-no\-history
|
|
3942
|
+
Do not record this run in the mock's start history.
|
|
3576
3943
|
|
|
3577
3944
|
.TP Examples:
|
|
3578
3945
|
|
|
3579
3946
|
Eg. postman mock run 12345678\-90ab\-cdef\-1234\-567890abcdef # by id, from Postman cloud
|
|
3580
3947
|
postman mock run ./postman/mocks/orders # by path, from your repository
|
|
3581
|
-
postman mock run ./postman/mocks/orders \-\-environment ./postman/environments/dev.
|
|
3948
|
+
postman mock run ./postman/mocks/orders \-\-environment ./postman/environments/dev.environment.yaml
|
|
3582
3949
|
postman mock run ./postman/mocks/orders \-\-port auto # pick any free port
|
|
3583
3950
|
postman mock run ./postman/mocks/orders \-\-port 4600 # use port 4600 (fails if it is in use)
|
|
3951
|
+
postman mock run ./postman/mocks/orders \-\-workspace <id> # record start history for a path run
|
|
3952
|
+
|
|
3953
|
+
Eligible runs are recorded in the mock's start history (source: cli) so they appear under
|
|
3954
|
+
"Previous starts" in Postman. Cloud ids record automatically; a manifest\-backed path run needs
|
|
3955
|
+
\-\-workspace. A raw handler with no mock id cannot be attributed and is not recorded.
|
|
3956
|
+
In CI the pipeline/branch is captured automatically. Best\-effort and never blocks the server;
|
|
3957
|
+
use \-\-no\-history to opt out.
|
|
3584
3958
|
|
|
3585
3959
|
Paths can be relative (e.g. ./postman/mocks/orders) or absolute (e.g. /Users/me/postman/mocks/orders).
|
|
3586
3960
|
|
|
@@ -3943,6 +4317,28 @@ Start mocks with fault\-injection scenarios defined in a .sim.yaml file
|
|
|
3943
4317
|
.B Usage:
|
|
3944
4318
|
[options] <filepath>
|
|
3945
4319
|
|
|
4320
|
+
.B Options:
|
|
4321
|
+
.TP
|
|
4322
|
+
.B \-w, \-\-workspace <id>
|
|
4323
|
+
Workspace that owns the run, for recording its simulation start history.
|
|
4324
|
+
.TP
|
|
4325
|
+
.B \-\-simulation <id>
|
|
4326
|
+
Simulation id to record start history against (a local .sim.yaml has only a name). Required, with \-\-workspace, to record history.
|
|
4327
|
+
.TP
|
|
4328
|
+
.B \-\-api\-key <key>
|
|
4329
|
+
Postman API key for recording start history (defaults to your `postman login` session).
|
|
4330
|
+
.TP
|
|
4331
|
+
.B \-\-no\-history
|
|
4332
|
+
Do not record this run in the simulation's start history.
|
|
4333
|
+
|
|
4334
|
+
.TP Examples:
|
|
4335
|
+
|
|
4336
|
+
Eligible runs are recorded in the simulation's start history (source: cli) so they appear
|
|
4337
|
+
under "Previous starts" in Postman. A parent start is recorded with one child start per member
|
|
4338
|
+
mock; pass \-\-workspace and \-\-simulation to enable it. In CI the pipeline/branch is captured
|
|
4339
|
+
automatically. Best\-effort and never blocks the servers; use \-\-no\-history to opt out.
|
|
4340
|
+
|
|
4341
|
+
|
|
3946
4342
|
.SS "describe"
|
|
3947
4343
|
[Beta] Get API context for AI coding agents directly from the command line.
|
|
3948
4344
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "postman-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.65.0",
|
|
4
4
|
"description": "Official Postman CLI - Command-line companion for API development, testing, and automation",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"postman",
|
|
@@ -49,19 +49,23 @@
|
|
|
49
49
|
"bin": {
|
|
50
50
|
"postman": "bin/postman.js"
|
|
51
51
|
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"postinstall": "node ./scripts/post-npm-installation.js"
|
|
54
|
+
},
|
|
52
55
|
"man": "./man/postman.1",
|
|
53
56
|
"files": [
|
|
54
57
|
"bin/",
|
|
55
58
|
"index.js",
|
|
56
59
|
"package.json",
|
|
57
60
|
"README.md",
|
|
58
|
-
"man/"
|
|
61
|
+
"man/",
|
|
62
|
+
"scripts/"
|
|
59
63
|
],
|
|
60
64
|
"optionalDependencies": {
|
|
61
|
-
"@postman/pm-bin-macos-arm64": "1.
|
|
62
|
-
"@postman/pm-bin-macos-x64": "1.
|
|
63
|
-
"@postman/pm-bin-linux-x64": "1.
|
|
64
|
-
"@postman/pm-bin-linux-arm64": "1.
|
|
65
|
-
"@postman/pm-bin-windows-x64": "1.
|
|
65
|
+
"@postman/pm-bin-macos-arm64": "1.65.0",
|
|
66
|
+
"@postman/pm-bin-macos-x64": "1.65.0",
|
|
67
|
+
"@postman/pm-bin-linux-x64": "1.65.0",
|
|
68
|
+
"@postman/pm-bin-linux-arm64": "1.65.0",
|
|
69
|
+
"@postman/pm-bin-windows-x64": "1.65.0"
|
|
66
70
|
}
|
|
67
71
|
}
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/* eslint-disable no-console */
|
|
4
|
+
/* eslint-disable one-var */
|
|
5
|
+
|
|
6
|
+
const fileSystem = require('node:fs');
|
|
7
|
+
const operatingSystem = require('node:os');
|
|
8
|
+
const path = require('node:path');
|
|
9
|
+
|
|
10
|
+
const POSTMAN_INSTRUCTION =
|
|
11
|
+
'Postman CLI is installed on this device, and can be used for API Engineering work.',
|
|
12
|
+
POSTMAN_INSTRUCTION_START = '<!-- postman-cli:installation:start -->',
|
|
13
|
+
POSTMAN_INSTRUCTION_END = '<!-- postman-cli:installation:end -->',
|
|
14
|
+
POSTMAN_INSTRUCTION_BLOCK = [
|
|
15
|
+
POSTMAN_INSTRUCTION_START,
|
|
16
|
+
POSTMAN_INSTRUCTION,
|
|
17
|
+
POSTMAN_INSTRUCTION_END
|
|
18
|
+
].join('\n'),
|
|
19
|
+
CLAUDE_PLUGIN_MESSAGE = [
|
|
20
|
+
'',
|
|
21
|
+
'Claude Code users and agents can use the Postman Plugin for Claude Code for full API lifecycle',
|
|
22
|
+
'management including documentation, collections, workspaces, environments, mocks, monitors right',
|
|
23
|
+
'from your repository.',
|
|
24
|
+
'',
|
|
25
|
+
'Install it with:',
|
|
26
|
+
' claude plugin install postman@claude-plugins-official',
|
|
27
|
+
'',
|
|
28
|
+
'Then start Claude Code and run:',
|
|
29
|
+
' /postman:setup'
|
|
30
|
+
].join('\n');
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @typedef {Object} AgentConfiguration
|
|
34
|
+
* @property {string} name - User-facing agent name.
|
|
35
|
+
* @property {string} configurationEnvironmentVariable - Environment override for the configuration root.
|
|
36
|
+
* @property {string} fallbackDirectory - Directory beneath the current user's home directory.
|
|
37
|
+
* @property {string[]} instructionFileNames - Ordered instruction files; the last is the fallback.
|
|
38
|
+
* @property {(context: AgentPostConfigurationContext) => void} [postConfiguration] - Agent follow-up.
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Selects the first existing instruction file, or the final configured fallback.
|
|
43
|
+
*
|
|
44
|
+
* @param {AgentConfiguration} agentConfiguration - Agent path conventions.
|
|
45
|
+
* @param {string} configurationRoot - Resolved agent configuration root.
|
|
46
|
+
* @returns {string} Absolute instruction-file path.
|
|
47
|
+
*/
|
|
48
|
+
function resolveInstructionFile (agentConfiguration, configurationRoot) {
|
|
49
|
+
const existingInstructionFileName = agentConfiguration.instructionFileNames.find(
|
|
50
|
+
(instructionFileName) => {
|
|
51
|
+
return fileSystem.existsSync(path.join(configurationRoot, instructionFileName));
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
return path.join(
|
|
56
|
+
configurationRoot,
|
|
57
|
+
existingInstructionFileName || agentConfiguration.instructionFileNames[
|
|
58
|
+
agentConfiguration.instructionFileNames.length - 1
|
|
59
|
+
]
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** @type {AgentConfiguration[]} */
|
|
64
|
+
const AGENT_CONFIGURATIONS = [
|
|
65
|
+
{
|
|
66
|
+
name: 'Claude Code',
|
|
67
|
+
configurationEnvironmentVariable: 'CLAUDE_CONFIG_DIR',
|
|
68
|
+
fallbackDirectory: '.claude',
|
|
69
|
+
instructionFileNames: ['CLAUDE.md'],
|
|
70
|
+
postConfiguration: ({ configurationResult, invocationDirectory }) => {
|
|
71
|
+
const projectConfigurationDetected = invocationDirectory ?
|
|
72
|
+
isDirectory(path.join(invocationDirectory, '.claude')) :
|
|
73
|
+
false;
|
|
74
|
+
|
|
75
|
+
if (configurationResult.detected || projectConfigurationDetected) {
|
|
76
|
+
console.log(CLAUDE_PLUGIN_MESSAGE);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: 'Codex',
|
|
82
|
+
configurationEnvironmentVariable: 'CODEX_HOME',
|
|
83
|
+
fallbackDirectory: '.codex',
|
|
84
|
+
instructionFileNames: ['AGENTS.override.md', 'AGENTS.md']
|
|
85
|
+
}
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @param {NodeJS.ProcessEnv} environment - Installation environment.
|
|
90
|
+
* @returns {boolean} Whether npm is installing the package globally.
|
|
91
|
+
*/
|
|
92
|
+
function isGlobalInstallation (environment) {
|
|
93
|
+
const globalSetting = String(environment.npm_config_global || '').toLowerCase();
|
|
94
|
+
|
|
95
|
+
return globalSetting === 'true' || globalSetting === '1';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @param {string} directory - Directory to inspect.
|
|
100
|
+
* @returns {boolean} Whether the path is an accessible directory.
|
|
101
|
+
*/
|
|
102
|
+
function isDirectory (directory) {
|
|
103
|
+
try {
|
|
104
|
+
return fileSystem.statSync(directory).isDirectory();
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* @param {unknown} error - Caught failure.
|
|
113
|
+
* @returns {string} Sanitized failure classification.
|
|
114
|
+
*/
|
|
115
|
+
function getErrorCode (error) {
|
|
116
|
+
try {
|
|
117
|
+
return error && typeof error.code === 'string' ? error.code : 'UNKNOWN';
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return 'UNKNOWN';
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Reporting must not turn this best-effort hook into a failed npm installation.
|
|
126
|
+
*
|
|
127
|
+
* @param {string} message - Sanitized warning to print.
|
|
128
|
+
* @returns {void}
|
|
129
|
+
*/
|
|
130
|
+
function printNonBlockingWarning (message) {
|
|
131
|
+
try {
|
|
132
|
+
console.warn(message);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// The post-install configuration remains non-critical when output is unavailable.
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* @param {NodeJS.ProcessEnv} environment - Installation environment.
|
|
141
|
+
* @param {string} userHome - Current user's home directory.
|
|
142
|
+
* @returns {string|null} Directory from which the user invoked npm.
|
|
143
|
+
*/
|
|
144
|
+
function resolveInvocationDirectory (environment, userHome) {
|
|
145
|
+
const initialDirectory = environment.INIT_CWD && environment.INIT_CWD.trim();
|
|
146
|
+
|
|
147
|
+
return initialDirectory ? path.resolve(userHome, initialDirectory) : null;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* @param {AgentConfiguration} agentConfiguration - Agent path conventions.
|
|
152
|
+
* @param {NodeJS.ProcessEnv} environment - Installation environment.
|
|
153
|
+
* @param {string} userHome - Current user's home directory.
|
|
154
|
+
* @param {string|null} invocationDirectory - Directory from which npm was invoked.
|
|
155
|
+
* @returns {string} Absolute agent configuration root.
|
|
156
|
+
*/
|
|
157
|
+
function resolveAgentConfigurationRoot (
|
|
158
|
+
agentConfiguration,
|
|
159
|
+
environment,
|
|
160
|
+
userHome,
|
|
161
|
+
invocationDirectory
|
|
162
|
+
) {
|
|
163
|
+
const configuredRoot = environment[agentConfiguration.configurationEnvironmentVariable];
|
|
164
|
+
|
|
165
|
+
if (configuredRoot && configuredRoot.trim()) {
|
|
166
|
+
return path.resolve(invocationDirectory || userHome, configuredRoot.trim());
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return path.join(userHome, agentConfiguration.fallbackDirectory);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Adds the Postman installation block without rewriting existing instructions.
|
|
174
|
+
*
|
|
175
|
+
* @param {string} instructionFile - Instruction file to update.
|
|
176
|
+
* @returns {'added'|'existing'} Update result.
|
|
177
|
+
* @throws {NodeJS.ErrnoException} When the instruction file cannot be read or appended.
|
|
178
|
+
*/
|
|
179
|
+
function addPostmanInstruction (instructionFile) {
|
|
180
|
+
let existingInstructions = '';
|
|
181
|
+
|
|
182
|
+
try {
|
|
183
|
+
existingInstructions = fileSystem.readFileSync(instructionFile, 'utf8');
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
if (error.code !== 'ENOENT') {
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (existingInstructions.includes(POSTMAN_INSTRUCTION_START) ||
|
|
192
|
+
existingInstructions.includes(POSTMAN_INSTRUCTION)) {
|
|
193
|
+
return 'existing';
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const separator = existingInstructions.length === 0 ?
|
|
197
|
+
'' :
|
|
198
|
+
existingInstructions.endsWith('\n') ? '\n' : '\n\n';
|
|
199
|
+
|
|
200
|
+
fileSystem.appendFileSync(
|
|
201
|
+
instructionFile,
|
|
202
|
+
`${separator}${POSTMAN_INSTRUCTION_BLOCK}\n`,
|
|
203
|
+
'utf8'
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
return 'added';
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* @typedef {Object} AgentConfigurationResult
|
|
211
|
+
* @property {string} name - User-facing agent name.
|
|
212
|
+
* @property {boolean} detected - Whether its global configuration root exists.
|
|
213
|
+
* @property {'added'|'existing'|null} instruction - Instruction update outcome.
|
|
214
|
+
* @property {string|null} errorCode - Sanitized failure classification.
|
|
215
|
+
*/
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* @typedef {Object} AgentPostConfigurationContext
|
|
219
|
+
* @property {AgentConfigurationResult} configurationResult - Agent configuration outcome.
|
|
220
|
+
* @property {string|null} invocationDirectory - Directory from which npm was invoked.
|
|
221
|
+
*/
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* @param {AgentConfiguration} agentConfiguration - Agent path conventions.
|
|
225
|
+
* @param {NodeJS.ProcessEnv} environment - Installation environment.
|
|
226
|
+
* @param {string} userHome - Current user's home directory.
|
|
227
|
+
* @param {string|null} invocationDirectory - Directory from which npm was invoked.
|
|
228
|
+
* @returns {AgentConfigurationResult} Detection and update result.
|
|
229
|
+
*/
|
|
230
|
+
function configureAgent (agentConfiguration, environment, userHome, invocationDirectory) {
|
|
231
|
+
let detected = false;
|
|
232
|
+
|
|
233
|
+
try {
|
|
234
|
+
const configurationRoot = resolveAgentConfigurationRoot(
|
|
235
|
+
agentConfiguration,
|
|
236
|
+
environment,
|
|
237
|
+
userHome,
|
|
238
|
+
invocationDirectory
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
if (!isDirectory(configurationRoot)) {
|
|
242
|
+
return {
|
|
243
|
+
name: agentConfiguration.name,
|
|
244
|
+
detected,
|
|
245
|
+
instruction: null,
|
|
246
|
+
errorCode: null
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
detected = true;
|
|
251
|
+
|
|
252
|
+
return {
|
|
253
|
+
name: agentConfiguration.name,
|
|
254
|
+
detected,
|
|
255
|
+
instruction: addPostmanInstruction(
|
|
256
|
+
resolveInstructionFile(agentConfiguration, configurationRoot)
|
|
257
|
+
),
|
|
258
|
+
errorCode: null
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
return {
|
|
263
|
+
name: agentConfiguration.name,
|
|
264
|
+
detected,
|
|
265
|
+
instruction: null,
|
|
266
|
+
errorCode: getErrorCode(error)
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Prints a concise result without exposing user-specific filesystem paths.
|
|
273
|
+
*
|
|
274
|
+
* @param {AgentConfigurationResult} result - Agent configuration result.
|
|
275
|
+
* @returns {void}
|
|
276
|
+
*/
|
|
277
|
+
function printAgentResult (result) {
|
|
278
|
+
if (result.instruction === 'added') {
|
|
279
|
+
console.log(`Added Postman CLI availability to ${result.name} global instructions.`);
|
|
280
|
+
}
|
|
281
|
+
else if (result.instruction === 'existing') {
|
|
282
|
+
console.log(`${result.name} global instructions already include Postman CLI.`);
|
|
283
|
+
}
|
|
284
|
+
else if (result.errorCode) {
|
|
285
|
+
printNonBlockingWarning(
|
|
286
|
+
`Could not update ${result.name} global instructions (${result.errorCode}); ` +
|
|
287
|
+
'the Postman CLI installation is still usable.'
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Runs an agent-specific follow-up without affecting other agents or npm.
|
|
294
|
+
*
|
|
295
|
+
* @param {AgentConfiguration} agentConfiguration - Agent path conventions.
|
|
296
|
+
* @param {AgentConfigurationResult} configurationResult - Agent configuration outcome.
|
|
297
|
+
* @param {string|null} invocationDirectory - Directory from which npm was invoked.
|
|
298
|
+
* @returns {void}
|
|
299
|
+
*/
|
|
300
|
+
function runAgentPostConfiguration (
|
|
301
|
+
agentConfiguration,
|
|
302
|
+
configurationResult,
|
|
303
|
+
invocationDirectory
|
|
304
|
+
) {
|
|
305
|
+
if (!agentConfiguration.postConfiguration) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
try {
|
|
310
|
+
agentConfiguration.postConfiguration({
|
|
311
|
+
configurationResult,
|
|
312
|
+
invocationDirectory
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
catch (error) {
|
|
316
|
+
printNonBlockingWarning(
|
|
317
|
+
`Could not complete ${agentConfiguration.name} post-configuration ` +
|
|
318
|
+
`(${getErrorCode(error)}); the Postman CLI installation is still usable.`
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Configures supported agents after a global npm installation.
|
|
325
|
+
*
|
|
326
|
+
* Instruction updates are deliberately non-critical. Installing the Postman CLI
|
|
327
|
+
* must still succeed when an agent configuration is read-only or malformed.
|
|
328
|
+
*
|
|
329
|
+
* @param {NodeJS.ProcessEnv} [environment] - Installation environment.
|
|
330
|
+
* @returns {void}
|
|
331
|
+
*/
|
|
332
|
+
function runPostInstallation (environment = process.env) {
|
|
333
|
+
try {
|
|
334
|
+
if (!isGlobalInstallation(environment)) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const userHome = operatingSystem.homedir(),
|
|
339
|
+
invocationDirectory = resolveInvocationDirectory(environment, userHome),
|
|
340
|
+
configuredAgents = AGENT_CONFIGURATIONS.map((agentConfiguration) => {
|
|
341
|
+
return {
|
|
342
|
+
agentConfiguration,
|
|
343
|
+
configurationResult: configureAgent(
|
|
344
|
+
agentConfiguration,
|
|
345
|
+
environment,
|
|
346
|
+
userHome,
|
|
347
|
+
invocationDirectory
|
|
348
|
+
)
|
|
349
|
+
};
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
console.log('Postman CLI is installed and can be used for API Engineering work.');
|
|
353
|
+
configuredAgents.forEach(({ configurationResult }) => {
|
|
354
|
+
try {
|
|
355
|
+
printAgentResult(configurationResult);
|
|
356
|
+
}
|
|
357
|
+
catch (error) {
|
|
358
|
+
printNonBlockingWarning(
|
|
359
|
+
`Could not report ${configurationResult.name} configuration ` +
|
|
360
|
+
`(${getErrorCode(error)}); the Postman CLI installation is still usable.`
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
configuredAgents.forEach(({ agentConfiguration, configurationResult }) => {
|
|
365
|
+
runAgentPostConfiguration(
|
|
366
|
+
agentConfiguration,
|
|
367
|
+
configurationResult,
|
|
368
|
+
invocationDirectory
|
|
369
|
+
);
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
catch (error) {
|
|
373
|
+
printNonBlockingWarning(
|
|
374
|
+
`Could not configure coding agents after installing Postman CLI (${getErrorCode(error)}); ` +
|
|
375
|
+
'the Postman CLI installation is still usable.'
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
if (require.main === module) {
|
|
381
|
+
try {
|
|
382
|
+
runPostInstallation();
|
|
383
|
+
}
|
|
384
|
+
catch (error) {
|
|
385
|
+
printNonBlockingWarning(
|
|
386
|
+
`Could not run Postman CLI post-installation (${getErrorCode(error)}); ` +
|
|
387
|
+
'the Postman CLI installation is still usable.'
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
finally {
|
|
391
|
+
process.exitCode = 0;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
module.exports = {
|
|
396
|
+
AGENT_CONFIGURATIONS,
|
|
397
|
+
POSTMAN_INSTRUCTION,
|
|
398
|
+
addPostmanInstruction,
|
|
399
|
+
isGlobalInstallation,
|
|
400
|
+
resolveAgentConfigurationRoot,
|
|
401
|
+
runPostInstallation
|
|
402
|
+
};
|