@evnx/cli 0.2.1 → 0.3.1

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 (3) hide show
  1. package/README.md +483 -0
  2. package/install.js +4 -5
  3. package/package.json +10 -9
package/README.md ADDED
@@ -0,0 +1,483 @@
1
+ # evnx
2
+
3
+ [![CI](https://github.com/urwithajit9/evnx/workflows/CI/badge.svg)](https://github.com/urwithajit9/evnx/actions)
4
+ [![Release](https://img.shields.io/github/v/release/urwithajit9/evnx)](https://github.com/urwithajit9/evnx/releases)
5
+ [![crates.io](https://img.shields.io/crates/v/evnx.svg)](https://crates.io/crates/evnx)
6
+ [![PyPI](https://img.shields.io/pypi/v/evnx.svg)](https://pypi.org/project/evnx/)
7
+ [![npm](https://img.shields.io/npm/v/@evnx/cli.svg)](https://www.npmjs.com/package/@evnx/cli)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+
10
+ A CLI tool for managing `.env` files — validation, secret scanning, format conversion, and migration to cloud secret managers.
11
+
12
+ [Website](https://www.evnx.dev) | [Getting Started](./docs/GETTING_STARTED.md) | [Changelog](./CHANGELOG.md)
13
+
14
+ ---
15
+
16
+ ## Why evnx?
17
+
18
+ Accidentally committing secrets to version control is one of the most common and costly developer mistakes. evnx is a local-first tool that catches misconfigurations, detects credential leaks, and converts environment files to the format each deployment target expects — before anything reaches CI or production.
19
+
20
+ ---
21
+
22
+ ## Installation
23
+
24
+ ### Linux / macOS
25
+
26
+ ```bash
27
+ curl -sSL https://raw.githubusercontent.com/urwithajit9/evnx/main/scripts/install.sh | bash
28
+ ```
29
+
30
+ ### Homebrew (macOS and Linux)
31
+
32
+ ```bash
33
+ brew install urwithajit9/evnx/evnx
34
+ ```
35
+
36
+ ### npm
37
+
38
+ ```bash
39
+ npm install -g @evnx/cli
40
+ ```
41
+
42
+ ### pipx (recommended for Python environments)
43
+ ```bash
44
+ pipx install evnx
45
+ ```
46
+
47
+ pipx installs CLI tools into isolated environments and wires them to your
48
+ system PATH automatically. It is the correct tool for installing Python-
49
+ distributed CLI binaries like evnx.
50
+
51
+ **Don't have pipx?**
52
+
53
+ **macOS**
54
+ ```bash
55
+ brew install pipx
56
+ pipx ensurepath
57
+ ```
58
+
59
+ **Ubuntu / Debian (Python 3.11+)**
60
+ ```bash
61
+ sudo apt install pipx
62
+ pipx ensurepath
63
+ ```
64
+ On older Ubuntu (20.04 and below) where `pipx` is not in apt:
65
+ ```bash
66
+ pip install --user pipx
67
+ python -m pipx ensurepath
68
+ ```
69
+ Note: `pip install evnx` will fail on Ubuntu 22.04+ with an "externally managed
70
+ environment" error (PEP 668). This is intentional — Ubuntu protects the system
71
+ Python. Use pipx instead.
72
+
73
+ **Windows**
74
+ ```powershell
75
+ python -m pip install --user pipx
76
+ python -m pipx ensurepath
77
+ ```
78
+ After running `ensurepath`, close and reopen your terminal (a full logout/login
79
+ may be required for PATH changes to take effect), then:
80
+ ```powershell
81
+ pipx install evnx
82
+ ```
83
+
84
+ After installing pipx on any platform, restart your terminal and run:
85
+ ```bash
86
+ pipx install evnx
87
+ evnx --version
88
+ ```
89
+
90
+ ### Cargo
91
+
92
+ ```bash
93
+ cargo install evnx
94
+ # with all optional features
95
+ cargo install evnx --all-features
96
+ ```
97
+
98
+ ### Windows
99
+
100
+ Install [Rust](https://rustup.rs/) first, then:
101
+
102
+ ```powershell
103
+ cargo install evnx
104
+ evnx --version
105
+ ```
106
+
107
+ ### Verify
108
+
109
+ ```bash
110
+ evnx --version
111
+ evnx --help
112
+ ```
113
+
114
+ ---
115
+
116
+ ## Commands
117
+
118
+ ### `evnx init`
119
+
120
+ Interactive project setup. Creates `.env` and `.env.example` files for your project through a guided TUI.
121
+
122
+ ```
123
+ evnx init
124
+ ```
125
+
126
+ Running `evnx init` launches an interactive menu with three modes:
127
+
128
+ ```
129
+ How do you want to start?
130
+ Blank — create empty .env files
131
+ Blueprint — use a pre-configured stack (Python, Node.js, Rust, Go, PHP, and more)
132
+ Architect — build a custom stack by selecting services interactively
133
+ ```
134
+
135
+ There are no flags required. The interactive flow handles stack and service selection inside the TUI.
136
+
137
+ ---
138
+
139
+ ### `evnx add`
140
+
141
+ Add variables to an existing `.env` file interactively. Supports custom input, service blueprints, and variable templates.
142
+
143
+ ```bash
144
+ evnx add
145
+ ```
146
+
147
+ ---
148
+
149
+ ### `evnx validate`
150
+
151
+ Validates your `.env` file for common misconfigurations before deployment.
152
+
153
+ ```bash
154
+ evnx validate # pretty output
155
+ evnx validate --strict # exit non-zero on warnings
156
+ evnx validate --format json # machine-readable output
157
+ evnx validate --format github-actions # inline GitHub annotations
158
+ ```
159
+
160
+ Detects: missing required variables, placeholder values (`YOUR_KEY_HERE`, `CHANGE_ME`), the boolean string trap (`DEBUG="False"` is truthy in most runtimes), weak secret keys, localhost in production, and suspicious port numbers.
161
+
162
+ ---
163
+
164
+ ### `evnx scan`
165
+
166
+ Scans files for accidentally committed credentials using pattern matching and entropy analysis.
167
+
168
+ ```bash
169
+ evnx scan # scan current directory
170
+ evnx scan --path src/ # specific path
171
+ evnx scan --format sarif # SARIF output for GitHub Security tab
172
+ evnx scan --exit-zero # warn but do not fail CI
173
+ ```
174
+
175
+ Detects: AWS Access Keys, Stripe keys (live and test), GitHub tokens, OpenAI and Anthropic API keys, RSA/EC/OpenSSH private keys, high-entropy strings, and generic API key patterns.
176
+
177
+ ---
178
+
179
+ ### `evnx diff`
180
+
181
+ Compares `.env` and `.env.example` and shows what is missing, extra, or mismatched.
182
+
183
+ ```bash
184
+ evnx diff # compare .env vs .env.example
185
+ evnx diff --show-values # include actual values
186
+ evnx diff --reverse # swap comparison direction
187
+ evnx diff --format json # JSON output
188
+ ```
189
+
190
+ ---
191
+
192
+ ### `evnx convert`
193
+
194
+ Converts your `.env` file to 14+ output formats for various deployment targets.
195
+
196
+ ```bash
197
+ evnx convert --to json
198
+ evnx convert --to yaml
199
+ evnx convert --to shell
200
+ evnx convert --to docker-compose
201
+ evnx convert --to kubernetes
202
+ evnx convert --to terraform
203
+ evnx convert --to github-actions
204
+ evnx convert --to aws-secrets
205
+ evnx convert --to gcp-secrets
206
+ evnx convert --to azure-keyvault
207
+ evnx convert --to heroku
208
+ evnx convert --to vercel
209
+ evnx convert --to railway
210
+ evnx convert --to doppler
211
+ ```
212
+
213
+ Advanced filtering and transformation:
214
+
215
+ ```bash
216
+ evnx convert --to json \
217
+ --output secrets.json \
218
+ --include "AWS_*" \
219
+ --exclude "*_LOCAL" \
220
+ --prefix "APP_" \
221
+ --transform uppercase \
222
+ --base64
223
+ ```
224
+
225
+ Pipe directly to AWS Secrets Manager:
226
+
227
+ ```bash
228
+ evnx convert --to aws-secrets | \
229
+ aws secretsmanager create-secret \
230
+ --name prod/myapp/config \
231
+ --secret-string file:///dev/stdin
232
+ ```
233
+
234
+ ---
235
+
236
+ ### `evnx sync`
237
+
238
+ Keeps `.env` and `.env.example` aligned, in either direction.
239
+
240
+ ```bash
241
+ # Forward: .env → .env.example (document what you have)
242
+ evnx sync --direction forward --placeholder
243
+
244
+ # Reverse: .env.example → .env (generate env from template)
245
+ evnx sync --direction reverse
246
+ ```
247
+
248
+ ---
249
+
250
+ ### `evnx migrate` _(requires `--features migrate`)_
251
+
252
+ Migrates secrets directly to cloud secret managers.
253
+
254
+ ```bash
255
+ # GitHub Actions secrets
256
+ evnx migrate --from env-file --to github-actions \
257
+ --repo owner/repo --github-token $GITHUB_TOKEN
258
+
259
+ # AWS Secrets Manager
260
+ evnx migrate --to aws-secrets-manager --secret-name prod/myapp/config
261
+
262
+ # Doppler (with dry run)
263
+ evnx migrate --to doppler --dry-run
264
+ ```
265
+
266
+ ---
267
+
268
+ ### `evnx doctor`
269
+
270
+ Runs a health check on your environment configuration setup.
271
+
272
+ ```bash
273
+ evnx doctor # check current directory
274
+ evnx doctor --path /path/to/project
275
+ ```
276
+
277
+ Checks: `.env` exists and has secure permissions, `.env` is in `.gitignore`, `.env.example` is tracked by Git, and project structure detection.
278
+
279
+ ---
280
+
281
+ ### `evnx template`
282
+
283
+ Generates configuration files from templates using `.env` variable substitution.
284
+
285
+ ```bash
286
+ evnx template \
287
+ --input config.template.yml \
288
+ --output config.yml \
289
+ --env .env
290
+ ```
291
+
292
+ Supported inline filters:
293
+
294
+ ```yaml
295
+ database:
296
+ host: {{DB_HOST}}
297
+ port: {{DB_PORT|int}}
298
+ ssl: {{DB_SSL|bool}}
299
+ name: {{DB_NAME|upper}}
300
+ ```
301
+
302
+ ---
303
+
304
+ ### `evnx backup` / `evnx restore` _(requires `--features backup`)_
305
+
306
+ Creates and restores AES-256-GCM encrypted backups using Argon2 key derivation.
307
+
308
+ ```bash
309
+ evnx backup .env --output .env.backup
310
+ evnx restore .env.backup --output .env
311
+ ```
312
+
313
+ ---
314
+
315
+ ## CI/CD Integration
316
+
317
+ ### GitHub Actions
318
+
319
+ ```yaml
320
+ name: Validate environment
321
+
322
+ on: [push, pull_request]
323
+
324
+ jobs:
325
+ validate:
326
+ runs-on: ubuntu-latest
327
+ steps:
328
+ - uses: actions/checkout@v4
329
+
330
+ - name: Install evnx
331
+ run: |
332
+ curl -sSL https://raw.githubusercontent.com/urwithajit9/evnx/main/scripts/install.sh | bash
333
+
334
+ - name: Validate configuration
335
+ run: evnx validate --strict --format github-actions
336
+
337
+ - name: Scan for secrets
338
+ run: evnx scan --format sarif > scan-results.sarif
339
+
340
+ - name: Upload SARIF
341
+ uses: github/codeql-action/upload-sarif@v3
342
+ if: always()
343
+ with:
344
+ sarif_file: scan-results.sarif
345
+ ```
346
+
347
+ ### GitLab CI
348
+
349
+ ```yaml
350
+ validate-env:
351
+ stage: validate
352
+ image: alpine:latest
353
+ before_script:
354
+ - apk add --no-cache curl bash
355
+ - curl -sSL https://raw.githubusercontent.com/urwithajit9/evnx/main/scripts/install.sh | bash
356
+ script:
357
+ - evnx validate --strict --format json
358
+ - evnx scan --format sarif > scan.sarif
359
+ artifacts:
360
+ reports:
361
+ sast: scan.sarif
362
+ ```
363
+
364
+ ### Pre-commit hook
365
+
366
+ ```yaml
367
+ # .pre-commit-config.yaml
368
+ repos:
369
+ - repo: local
370
+ hooks:
371
+ - id: evnx-validate
372
+ name: Validate .env files
373
+ entry: evnx validate --strict
374
+ language: system
375
+ pass_filenames: false
376
+
377
+ - id: evnx-scan
378
+ name: Scan for secrets
379
+ entry: evnx scan --exit-zero
380
+ language: system
381
+ pass_filenames: false
382
+ ```
383
+
384
+ ---
385
+
386
+ ## Configuration
387
+
388
+ Store defaults in `.evnx.toml` at the project root:
389
+
390
+ ```toml
391
+ [defaults]
392
+ env_file = ".env"
393
+ example_file = ".env.example"
394
+ verbose = false
395
+
396
+ [validate]
397
+ strict = true
398
+ auto_fix = false
399
+ format = "pretty"
400
+
401
+ [scan]
402
+ ignore_placeholders = true
403
+ exclude_patterns = ["*.example", "*.sample", "*.template"]
404
+ format = "pretty"
405
+
406
+ [convert]
407
+ default_format = "json"
408
+ base64 = false
409
+
410
+ [aliases]
411
+ gh = "github-actions"
412
+ k8s = "kubernetes"
413
+ tf = "terraform"
414
+ ```
415
+
416
+ ---
417
+
418
+ ## Known Limitations
419
+
420
+ **Array and multiline values** — evnx follows the strict `.env` spec where values are simple strings. The following will not parse correctly:
421
+
422
+ ```bash
423
+ # Not supported
424
+ CORS_ALLOWED=["https://example.com", "https://admin.example.com"]
425
+ CONFIG={"key": "value"}
426
+ DATABASE_HOSTS="""
427
+ host1.example.com
428
+ host2.example.com
429
+ """
430
+ ```
431
+
432
+ Use comma-separated strings and parse them in application code. A `--lenient` flag for extended syntax is under consideration — see [open issues](https://github.com/urwithajit9/evnx/issues).
433
+
434
+ **Windows** — file permissions checking is limited (no Unix permission model). Terminal color support requires PowerShell or Windows Terminal on older systems.
435
+
436
+ ---
437
+
438
+ ## Development
439
+
440
+ ```bash
441
+ git clone https://github.com/urwithajit9/evnx.git
442
+ cd evnx
443
+
444
+ cargo build # core features only
445
+ cargo build --all-features
446
+ cargo test
447
+ cargo clippy --all-features -- -D warnings
448
+ cargo fmt
449
+ ```
450
+
451
+ Feature flags:
452
+
453
+ ```toml
454
+ [features]
455
+ default = []
456
+ migrate = ["reqwest", "base64", "indicatif"]
457
+ backup = ["aes-gcm", "argon2", "rand"]
458
+ full = ["migrate", "backup"]
459
+ ```
460
+
461
+ ---
462
+
463
+ ## Contributing
464
+
465
+ See [CONTRIBUTING.md](CONTRIBUTING.md). Contributions are welcome in: additional format converters, secret pattern improvements, Windows enhancements, extended `.env` format support, and integration examples.
466
+
467
+ ---
468
+
469
+ ## License
470
+
471
+ MIT — see [LICENSE](LICENSE).
472
+
473
+ ---
474
+
475
+ ## Credits
476
+
477
+ Built by [Ajit Kumar](https://github.com/urwithajit9).
478
+
479
+ Related projects: [python-dotenv](https://github.com/theskumar/python-dotenv), [dotenvy](https://github.com/allan2/dotenvy), [direnv](https://direnv.net/), [git-secrets](https://github.com/awslabs/git-secrets).
480
+
481
+ ---
482
+
483
+ [Website](https://www.evnx.dev) | [Issues](https://github.com/urwithajit9/evnx/issues) | [Discussions](https://github.com/urwithajit9/evnx/discussions) | [Email](mailto:support@evnx.dev)
package/install.js CHANGED
@@ -36,9 +36,9 @@ function getBinaryPath() {
36
36
  );
37
37
  }
38
38
 
39
- const pkgDir = path.dirname(pkgJsonPath);
40
- const binName = process.platform === "win32" ? "evnx.exe" : "evnx";
41
- const binPath = path.join(pkgDir, "bin", binName);
39
+ const pkgDir = path.dirname(pkgJsonPath);
40
+ const binName = process.platform === "win32" ? "evnx.exe" : "evnx";
41
+ const binPath = path.join(pkgDir, "bin", binName);
42
42
 
43
43
  if (!fs.existsSync(binPath)) {
44
44
  throw new Error(`evnx: Binary not found at expected path: ${binPath}`);
@@ -56,7 +56,7 @@ try {
56
56
  const shim = `@echo off\r\n"${binaryPath}" %*\r\n`;
57
57
  fs.writeFileSync(path.join(binDir, "evnx.cmd"), shim);
58
58
  } else {
59
- const shim = `#!/bin/sh\nexec "${binaryPath}" "$@"\n`;
59
+ const shim = `#!/bin/sh\nexec "${binaryPath}" "$@"\n`;
60
60
  const shimPath = path.join(binDir, "evnx");
61
61
  fs.writeFileSync(shimPath, shim);
62
62
  fs.chmodSync(shimPath, 0o755);
@@ -64,7 +64,6 @@ try {
64
64
 
65
65
  console.log(`evnx installed for ${process.platform}/${process.arch}`);
66
66
  } catch (err) {
67
- // Non-fatal — don't block npm install, just warn
68
67
  process.stderr.write(`\nWARNING: ${err.message}\n\n`);
69
68
  process.exit(0);
70
69
  }
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@evnx/cli",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "CLI tool for managing .env files — validation, secret scanning, format conversion",
5
5
  "keywords": ["dotenv", "env", "secrets", "cli", "security", "devtools", "environment"],
6
- "author": "Ajit Kumar <support@dotenv.space>",
6
+ "author": "Ajit Kumar <support@evnx.dev>",
7
7
  "license": "MIT",
8
- "homepage": "https://dotenv.space",
8
+ "homepage": "https://www.evnx.dev",
9
9
  "repository": {
10
10
  "type": "git",
11
11
  "url": "https://github.com/urwithajit9/evnx.git"
@@ -20,17 +20,18 @@
20
20
  "postinstall": "node install.js"
21
21
  },
22
22
  "optionalDependencies": {
23
- "@evnx/evnx-linux-x64": "0.2.1",
24
- "@evnx/evnx-linux-arm64": "0.2.1",
25
- "@evnx/evnx-darwin-x64": "0.2.1",
26
- "@evnx/evnx-darwin-arm64": "0.2.1",
27
- "@evnx/evnx-win32-x64": "0.2.1"
23
+ "@evnx/evnx-linux-x64": "0.3.1",
24
+ "@evnx/evnx-linux-arm64": "0.3.1",
25
+ "@evnx/evnx-darwin-x64": "0.3.1",
26
+ "@evnx/evnx-darwin-arm64": "0.3.1",
27
+ "@evnx/evnx-win32-x64": "0.3.1"
28
28
  },
29
29
  "engines": {
30
30
  "node": ">=14"
31
31
  },
32
32
  "files": [
33
33
  "bin/",
34
- "install.js"
34
+ "install.js",
35
+ "README.md"
35
36
  ]
36
37
  }