@dotenvx/dotenvx 2.19.0 → 2.19.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,7 +2,19 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
- [Unreleased](https://github.com/dotenvx/dotenvx/compare/v2.19.0...main)
5
+ [Unreleased](https://github.com/dotenvx/dotenvx/compare/v2.19.2...main)
6
+
7
+ ## [2.19.2](https://github.com/dotenvx/dotenvx/compare/v2.19.1...v2.19.2) (2026-08-03)
8
+
9
+ ### Changed
10
+
11
+ * Example `.env.vault` from precommit ([#935](https://github.com/dotenvx/dotenvx/pull/935))
12
+
13
+ ## [2.19.1](https://github.com/dotenvx/dotenvx/compare/v2.19.0...v2.19.1) (2026-07-29)
14
+
15
+ ### Changed
16
+
17
+ * User can click enter to open up approval url for convenience ([#934](https://github.com/dotenvx/dotenvx/pull/934))
6
18
 
7
19
  ## [2.19.0](https://github.com/dotenvx/dotenvx/compare/v2.18.1...v2.19.0) (2026-07-27)
8
20
 
package/README.md CHANGED
@@ -130,6 +130,13 @@ More examples
130
130
 
131
131
  Run Claude with your real secrets while redacting them from its output.
132
132
 
133
+ Prerequisite: install [Claude Code](https://code.claude.com/docs/en/setup) to get the `claude` command.
134
+
135
+ ```sh
136
+ $ curl -fsSL https://claude.ai/install.sh | bash
137
+ $ claude --version
138
+ ```
139
+
133
140
  ```sh
134
141
  $ echo "HELLO=World" > .env
135
142
 
@@ -144,6 +151,13 @@ see [Claude redaction guide](https://dotenvx.com/docs/cli/run-redact-claude-prin
144
151
 
145
152
  Run Codex with your real secrets while redacting them from its output.
146
153
 
154
+ Prerequisite: install the [Codex CLI](https://developers.openai.com/codex/cli/) to get the `codex` command.
155
+
156
+ ```sh
157
+ $ npm install -g @openai/codex
158
+ $ codex --version
159
+ ```
160
+
147
161
  ```sh
148
162
  $ echo "HELLO=World" > .env
149
163
 
@@ -153,6 +167,27 @@ Hello [REDACTED]
153
167
 
154
168
  see [Codex redaction guide](https://dotenvx.com/docs/cli/run-redact-codex-exec)
155
169
 
170
+ </details>
171
+ <details><summary>Cursor 🖱️</summary><br>
172
+
173
+ Run Cursor with your real secrets while redacting them from its output.
174
+
175
+ Prerequisite: install the separate [Cursor CLI](https://cursor.com/cli). Installing the Cursor desktop app does not necessarily install the `agent` command.
176
+
177
+ ```sh
178
+ $ curl https://cursor.com/install -fsS | bash
179
+ $ agent --version
180
+ ```
181
+
182
+ ```sh
183
+ $ echo "HELLO=World" > .env
184
+
185
+ $ dotenvx run --redact -- agent -p --force 'Run `dotenvx get HELLO` and echo back just Hello VALUE' --output-format text
186
+ Hello [REDACTED]
187
+ ```
188
+
189
+ see [Cursor redaction guide](https://dotenvx.com/docs/secrets-in-cursor)
190
+
156
191
  </details>
157
192
  <details><summary>1Password 🔐</summary><br>
158
193
 
@@ -1734,6 +1769,37 @@ Turn off OS secret store lookups for get.
1734
1769
  $ dotenvx get HELLO --no-native
1735
1770
  ```
1736
1771
 
1772
+ </details>
1773
+ <details><summary>`get KEY --no-armor`</summary><br>
1774
+
1775
+ Turn off [Dotenvx Armor ⛨](https://dotenvx.com/armor) features for get.
1776
+
1777
+ ```sh
1778
+ $ dotenvx get HELLO --no-armor
1779
+ World
1780
+ ```
1781
+
1782
+ </details>
1783
+ <details><summary>`get KEY --ignore`</summary><br>
1784
+
1785
+ Ignore specific error codes.
1786
+
1787
+ ```sh
1788
+ $ dotenvx get HELLO --ignore=MISSING_ENV_FILE
1789
+ ```
1790
+
1791
+ Ignore multiple error codes by separating them with spaces.
1792
+
1793
+ ```sh
1794
+ $ dotenvx get HELLO --ignore=MISSING_ENV_FILE MISSING_KEY
1795
+ ```
1796
+
1797
+ You can also set `DOTENV_CONFIG_IGNORE`. Its value is a comma-separated list.
1798
+
1799
+ ```sh
1800
+ $ DOTENV_CONFIG_IGNORE=MISSING_ENV_FILE,OTHER dotenvx get HELLO
1801
+ ```
1802
+
1737
1803
  </details>
1738
1804
  <details><summary>`get KEY -f`</summary><br>
1739
1805
 
@@ -1880,6 +1946,20 @@ $ dotenvx get
1880
1946
  {"HELLO":"World"}
1881
1947
  ```
1882
1948
 
1949
+ </details>
1950
+ <details><summary>`get --pretty-print`</summary><br>
1951
+
1952
+ Make the JSON output more readable.
1953
+
1954
+ ```sh
1955
+ $ echo "HELLO=World" > .env
1956
+
1957
+ $ dotenvx get --pretty-print
1958
+ {
1959
+ "HELLO": "World"
1960
+ }
1961
+ ```
1962
+
1883
1963
  </details>
1884
1964
  <details><summary>`get -ik`</summary><br>
1885
1965
 
@@ -1904,6 +1984,18 @@ $ dotenvx get --format=eval-export -ek "DOTENV_PUBLIC_KEY*"
1904
1984
  export HELLO='World'
1905
1985
  ```
1906
1986
 
1987
+ </details>
1988
+ <details><summary>`get --format colon`</summary><br>
1989
+
1990
+ Return a colon-formatted response of all key/value pairs in a `.env` file.
1991
+
1992
+ ```sh
1993
+ $ echo "HELLO=World" > .env
1994
+
1995
+ $ dotenvx get --format colon
1996
+ HELLO: World
1997
+ ```
1998
+
1907
1999
  </details>
1908
2000
  <details><summary>`get --format shell`</summary><br>
1909
2001
 
@@ -2100,6 +2192,25 @@ Turn off OS secret store lookups for set.
2100
2192
  $ dotenvx set HELLO World --no-native
2101
2193
  ```
2102
2194
 
2195
+ </details>
2196
+ <details><summary>`set KEY value --no-armor`</summary><br>
2197
+
2198
+ Turn off [Dotenvx Armor ⛨](https://dotenvx.com/armor) features for set.
2199
+
2200
+ ```sh
2201
+ $ dotenvx set HELLO World --no-armor
2202
+ ◈ encrypted HELLO (.env)
2203
+ ```
2204
+
2205
+ </details>
2206
+ <details><summary>`set KEY value --no-create`</summary><br>
2207
+
2208
+ Do not create a missing `.env` file.
2209
+
2210
+ ```sh
2211
+ $ dotenvx set HELLO World -f .env.production --no-create
2212
+ ```
2213
+
2103
2214
  </details>
2104
2215
  <details><summary>`encrypt`</summary><br>
2105
2216
 
@@ -2149,6 +2260,25 @@ $ dotenvx encrypt --no-armor
2149
2260
  ◈ encrypted (.env)
2150
2261
  ```
2151
2262
 
2263
+ </details>
2264
+ <details><summary>`encrypt --token`</summary><br>
2265
+
2266
+ Set the Armor token.
2267
+
2268
+ ```sh
2269
+ $ dotenvx encrypt --token token
2270
+ ◈ encrypted (.env) · armored ⛨
2271
+ ```
2272
+
2273
+ </details>
2274
+ <details><summary>`encrypt --no-create`</summary><br>
2275
+
2276
+ Do not create a missing `.env` file.
2277
+
2278
+ ```sh
2279
+ $ dotenvx encrypt -f .env.production --no-create
2280
+ ```
2281
+
2152
2282
  </details>
2153
2283
  <details><summary>`encrypt -fk`</summary><br>
2154
2284
 
@@ -2278,6 +2408,16 @@ $ dotenvx decrypt --no-native
2278
2408
  ◇ decrypted (.env)
2279
2409
  ```
2280
2410
 
2411
+ </details>
2412
+ <details><summary>`decrypt --no-armor`</summary><br>
2413
+
2414
+ Turn off [Dotenvx Armor ⛨](https://dotenvx.com/armor) features for decrypt.
2415
+
2416
+ ```sh
2417
+ $ dotenvx decrypt --no-armor
2418
+ ◇ decrypted (.env)
2419
+ ```
2420
+
2281
2421
  </details>
2282
2422
  <details><summary>`decrypt -f`</summary><br>
2283
2423
 
@@ -2416,6 +2556,16 @@ $ dotenvx keypair --no-native
2416
2556
  {"DOTENV_PUBLIC_KEY":"<publicKey>","DOTENV_PRIVATE_KEY":"<privateKey>"}
2417
2557
  ```
2418
2558
 
2559
+ </details>
2560
+ <details><summary>`keypair --no-armor`</summary><br>
2561
+
2562
+ Turn off [Dotenvx Armor ⛨](https://dotenvx.com/armor) features for keypair.
2563
+
2564
+ ```sh
2565
+ $ dotenvx keypair --no-armor
2566
+ {"DOTENV_PUBLIC_KEY":"<publicKey>","DOTENV_PRIVATE_KEY":"<privateKey>"}
2567
+ ```
2568
+
2419
2569
  </details>
2420
2570
  <details><summary>`keypair -f`</summary><br>
2421
2571
 
@@ -2469,6 +2619,39 @@ $ dotenvx keypair --format shell
2469
2619
  DOTENV_PUBLIC_KEY=<publicKey> DOTENV_PRIVATE_KEY=<privateKey>
2470
2620
  ```
2471
2621
 
2622
+ </details>
2623
+ <details><summary>`keypair --format colon`</summary><br>
2624
+
2625
+ Return a colon-formatted keypair.
2626
+
2627
+ ```sh
2628
+ $ dotenvx keypair --format colon
2629
+ DOTENV_PUBLIC_KEY:<publicKey> DOTENV_PRIVATE_KEY:<privateKey>
2630
+ ```
2631
+
2632
+ </details>
2633
+ <details><summary>`keypair --format json`</summary><br>
2634
+
2635
+ Return a JSON-formatted keypair.
2636
+
2637
+ ```sh
2638
+ $ dotenvx keypair --format json
2639
+ {"DOTENV_PUBLIC_KEY":"<publicKey>","DOTENV_PRIVATE_KEY":"<privateKey>"}
2640
+ ```
2641
+
2642
+ </details>
2643
+ <details><summary>`keypair --pretty-print`</summary><br>
2644
+
2645
+ Make the JSON output more readable.
2646
+
2647
+ ```sh
2648
+ $ dotenvx keypair --pretty-print
2649
+ {
2650
+ "DOTENV_PUBLIC_KEY": "<publicKey>",
2651
+ "DOTENV_PRIVATE_KEY": "<privateKey>"
2652
+ }
2653
+ ```
2654
+
2472
2655
  </details>
2473
2656
  <details><summary>`ls`</summary><br>
2474
2657
 
@@ -2895,6 +3078,21 @@ Use a token when running non-interactively.
2895
3078
  $ dotenvx armor pull -f .env.production --token "$DOTENVX_ARMOR_TOKEN"
2896
3079
  ```
2897
3080
 
3081
+ </details>
3082
+ <details><summary>`armor open`</summary><br>
3083
+
3084
+ Open an armored key in your browser.
3085
+
3086
+ ```sh
3087
+ $ dotenvx armor open
3088
+ ```
3089
+
3090
+ Open the armored key for a specific env file.
3091
+
3092
+ ```sh
3093
+ $ dotenvx armor open -f .env.production
3094
+ ```
3095
+
2898
3096
  </details>
2899
3097
  <details><summary>`armor move`</summary><br>
2900
3098
 
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.19.0",
2
+ "version": "2.19.2",
3
3
  "name": "@dotenvx/dotenvx",
4
4
  "description": "a secure dotenv–from the creator of `dotenv`",
5
5
  "author": "@motdotla",
@@ -282,11 +282,16 @@ program.command('logout', { hidden: true })
282
282
  program.command('curl', { hidden: true })
283
283
  .description('Dotenvx Armor API')
284
284
  .addHelpText('after', help.curl)
285
- .argument('<url>', '(run dotenvx run --help for list of urls)')
285
+ .argument('[url]', '(run dotenvx curl --help for list of urls)')
286
286
  .option('-X, --request <method>', 'HTTP request method')
287
287
  .option('--data <json>', 'JSON request body')
288
288
  .option('--token <token>', 'set token')
289
289
  .action(function (...args) {
290
+ if (!this.args[0]) {
291
+ this.outputHelp()
292
+ return
293
+ }
294
+
290
295
  return require('./actions/curl').apply(this, args)
291
296
  })
292
297
 
package/src/cli/help.js CHANGED
@@ -105,20 +105,22 @@ Endpoints:
105
105
  GET /api/teams/:team/invitations
106
106
  POST /api/teams/:team/invitations
107
107
  DELETE /api/teams/:team/invitations/:id
108
+ GET /api/logs?team=:team
108
109
 
109
110
  Examples:
110
111
 
111
- dotenvx curl https://armor.dotenvx.com/api/account
112
- dotenvx curl https://armor.dotenvx.com/api/armor/keypairs
113
- dotenvx curl https://armor.dotenvx.com/api/armor/keypairs/PUBLIC_KEY
114
- dotenvx curl https://armor.dotenvx.com/api/armor/keypairs/PUBLIC_KEY/settings/guard --data '{"value":true}'
115
- dotenvx curl https://armor.dotenvx.com/api/armor/keypairs/PUBLIC_KEY/settings/enclave --data '{"value":true}'
116
- dotenvx curl https://armor.dotenvx.com/api/teams
117
- dotenvx curl https://armor.dotenvx.com/api/teams/TEAM
118
- dotenvx curl https://armor.dotenvx.com/api/teams/TEAM/members
119
- dotenvx curl https://armor.dotenvx.com/api/teams/TEAM/members
120
- dotenvx curl https://armor.dotenvx.com/api/teams/TEAM/invitations --data '{"email":"person@example.com","role":"member"}'
121
- dotenvx curl https://armor.dotenvx.com/api/teams/TEAM/invitations/123 --request DELETE
112
+ dotenvx curl "https://armor.dotenvx.com/api/account"
113
+ dotenvx curl "https://armor.dotenvx.com/api/armor/keypairs"
114
+ dotenvx curl "https://armor.dotenvx.com/api/armor/keypairs/PUBLIC_KEY"
115
+ dotenvx curl "https://armor.dotenvx.com/api/armor/keypairs/PUBLIC_KEY/settings/guard" --data '{"value":true}'
116
+ dotenvx curl "https://armor.dotenvx.com/api/armor/keypairs/PUBLIC_KEY/settings/enclave" --data '{"value":true}'
117
+ dotenvx curl "https://armor.dotenvx.com/api/teams"
118
+ dotenvx curl "https://armor.dotenvx.com/api/teams/TEAM"
119
+ dotenvx curl "https://armor.dotenvx.com/api/teams/TEAM/members"
120
+ dotenvx curl "https://armor.dotenvx.com/api/teams/TEAM/members"
121
+ dotenvx curl "https://armor.dotenvx.com/api/teams/TEAM/invitations" --data '{"email":"person@example.com","role":"member"}'
122
+ dotenvx curl "https://armor.dotenvx.com/api/teams/TEAM/invitations/123" --request DELETE
123
+ dotenvx curl "https://armor.dotenvx.com/api/logs?team=TEAM"
122
124
  `
123
125
  }
124
126
 
@@ -2,6 +2,8 @@ const Session = require('../../../db/session')
2
2
  const ArmorKeyring = require('../../services/armorKeyring')
3
3
  const armoredKeyDisplay = require('../../helpers/armoredKeyDisplay')
4
4
  const isNetworkError = require('../../helpers/isNetworkError')
5
+ const listenForOpenKey = require('../../helpers/listenForOpenKey')
6
+ const openUrl = require('../../helpers/openUrl')
5
7
 
6
8
  async function index (publicKeyHex, options = {}) {
7
9
  const sesh = new Session()
@@ -16,11 +18,13 @@ async function index (publicKeyHex, options = {}) {
16
18
  devicePublicKey,
17
19
  publicKeyHex
18
20
  )
21
+ let cleanupOpenKeyListener = () => {}
19
22
  if (options.onStatus) {
20
23
  keyring.onApprovalRequired = ({ approvalUri, code }) => {
21
24
  const keyDisplay = armoredKeyDisplay(publicKeyHex)
22
25
  const keySuffix = keyDisplay ? ` (${keyDisplay})` : ''
23
- options.onStatus(`[${code}] visit [${approvalUri}] and approve${keySuffix}`)
26
+ options.onStatus(`[${code}] press Enter to open [${approvalUri}] and approve${keySuffix}`)
27
+ cleanupOpenKeyListener = listenForOpenKey(() => openUrl(approvalUri))
24
28
  }
25
29
  }
26
30
 
@@ -32,6 +36,8 @@ async function index (publicKeyHex, options = {}) {
32
36
  }
33
37
 
34
38
  throw error
39
+ } finally {
40
+ cleanupOpenKeyListener()
35
41
  }
36
42
  }
37
43
 
@@ -43,7 +43,7 @@ class Prebuild {
43
43
 
44
44
  // check if that file is being ignored
45
45
  if (ig.ignores(file)) {
46
- if (file === '.env.example' || file === '.env.x') {
46
+ if (file === '.env.example' || file === '.env.vault' || file === '.env.x') {
47
47
  const warning = new Errors({
48
48
  message: `${file} ignored (should not be)`,
49
49
  help: `fix: [dotenvx gitignore --pattern !${file}]`
@@ -51,7 +51,7 @@ class Prebuild {
51
51
  warnings.push(warning)
52
52
  }
53
53
  } else {
54
- if (file !== '.env.example' && file !== '.env.x') {
54
+ if (file !== '.env.example' && file !== '.env.vault' && file !== '.env.x') {
55
55
  const src = fsx.readFileXSync(file)
56
56
  const encrypted = sealed(src)
57
57
 
@@ -60,7 +60,7 @@ class Precommit {
60
60
  if (this._isFileToBeCommitted(file)) {
61
61
  // check if that file is being ignored
62
62
  if (ig.ignores(file)) {
63
- if (filename === '.env.example' || filename === '.env.x') {
63
+ if (filename === '.env.example' || filename === '.env.vault' || filename === '.env.x') {
64
64
  const warning = new Errors({
65
65
  message: `${file} ignored (should not be)`,
66
66
  help: `fix: [dotenvx gitignore --pattern !${file}]`
@@ -68,7 +68,7 @@ class Precommit {
68
68
  warnings.push(warning)
69
69
  }
70
70
  } else {
71
- if (filename !== '.env.example' && filename !== '.env.x') {
71
+ if (filename !== '.env.example' && filename !== '.env.vault' && filename !== '.env.x') {
72
72
  const src = fsx.readFileXSync(file)
73
73
  const encrypted = sealed(src)
74
74