@evnx/cli 0.2.1 → 0.3.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.
Files changed (3) hide show
  1. package/README.md +438 -0
  2. package/install.js +4 -5
  3. package/package.json +10 -9
package/README.md ADDED
@@ -0,0 +1,438 @@
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
+ ### npm
31
+
32
+ ```bash
33
+ npm install -g @evnx/cli
34
+ ```
35
+
36
+ ### pipx (recommended for Python environments)
37
+
38
+ ```bash
39
+ pipx install evnx
40
+ ```
41
+
42
+ > `pip install evnx` also works but places the binary inside the active virtualenv's `bin/` directory.
43
+ > Use `pipx` to make `evnx` available system-wide without managing a virtualenv manually.
44
+
45
+ ### Cargo
46
+
47
+ ```bash
48
+ cargo install evnx
49
+ # with all optional features
50
+ cargo install evnx --all-features
51
+ ```
52
+
53
+ ### Windows
54
+
55
+ Install [Rust](https://rustup.rs/) first, then:
56
+
57
+ ```powershell
58
+ cargo install evnx
59
+ evnx --version
60
+ ```
61
+
62
+ ### Verify
63
+
64
+ ```bash
65
+ evnx --version
66
+ evnx --help
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Commands
72
+
73
+ ### `evnx init`
74
+
75
+ Interactive project setup. Creates `.env` and `.env.example` files for your project through a guided TUI.
76
+
77
+ ```
78
+ evnx init
79
+ ```
80
+
81
+ Running `evnx init` launches an interactive menu with three modes:
82
+
83
+ ```
84
+ How do you want to start?
85
+ Blank — create empty .env files
86
+ Blueprint — use a pre-configured stack (Python, Node.js, Rust, Go, PHP, and more)
87
+ Architect — build a custom stack by selecting services interactively
88
+ ```
89
+
90
+ There are no flags required. The interactive flow handles stack and service selection inside the TUI.
91
+
92
+ ---
93
+
94
+ ### `evnx add`
95
+
96
+ Add variables to an existing `.env` file interactively. Supports custom input, service blueprints, and variable templates.
97
+
98
+ ```bash
99
+ evnx add
100
+ ```
101
+
102
+ ---
103
+
104
+ ### `evnx validate`
105
+
106
+ Validates your `.env` file for common misconfigurations before deployment.
107
+
108
+ ```bash
109
+ evnx validate # pretty output
110
+ evnx validate --strict # exit non-zero on warnings
111
+ evnx validate --format json # machine-readable output
112
+ evnx validate --format github-actions # inline GitHub annotations
113
+ ```
114
+
115
+ 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.
116
+
117
+ ---
118
+
119
+ ### `evnx scan`
120
+
121
+ Scans files for accidentally committed credentials using pattern matching and entropy analysis.
122
+
123
+ ```bash
124
+ evnx scan # scan current directory
125
+ evnx scan --path src/ # specific path
126
+ evnx scan --format sarif # SARIF output for GitHub Security tab
127
+ evnx scan --exit-zero # warn but do not fail CI
128
+ ```
129
+
130
+ 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.
131
+
132
+ ---
133
+
134
+ ### `evnx diff`
135
+
136
+ Compares `.env` and `.env.example` and shows what is missing, extra, or mismatched.
137
+
138
+ ```bash
139
+ evnx diff # compare .env vs .env.example
140
+ evnx diff --show-values # include actual values
141
+ evnx diff --reverse # swap comparison direction
142
+ evnx diff --format json # JSON output
143
+ ```
144
+
145
+ ---
146
+
147
+ ### `evnx convert`
148
+
149
+ Converts your `.env` file to 14+ output formats for various deployment targets.
150
+
151
+ ```bash
152
+ evnx convert --to json
153
+ evnx convert --to yaml
154
+ evnx convert --to shell
155
+ evnx convert --to docker-compose
156
+ evnx convert --to kubernetes
157
+ evnx convert --to terraform
158
+ evnx convert --to github-actions
159
+ evnx convert --to aws-secrets
160
+ evnx convert --to gcp-secrets
161
+ evnx convert --to azure-keyvault
162
+ evnx convert --to heroku
163
+ evnx convert --to vercel
164
+ evnx convert --to railway
165
+ evnx convert --to doppler
166
+ ```
167
+
168
+ Advanced filtering and transformation:
169
+
170
+ ```bash
171
+ evnx convert --to json \
172
+ --output secrets.json \
173
+ --include "AWS_*" \
174
+ --exclude "*_LOCAL" \
175
+ --prefix "APP_" \
176
+ --transform uppercase \
177
+ --base64
178
+ ```
179
+
180
+ Pipe directly to AWS Secrets Manager:
181
+
182
+ ```bash
183
+ evnx convert --to aws-secrets | \
184
+ aws secretsmanager create-secret \
185
+ --name prod/myapp/config \
186
+ --secret-string file:///dev/stdin
187
+ ```
188
+
189
+ ---
190
+
191
+ ### `evnx sync`
192
+
193
+ Keeps `.env` and `.env.example` aligned, in either direction.
194
+
195
+ ```bash
196
+ # Forward: .env → .env.example (document what you have)
197
+ evnx sync --direction forward --placeholder
198
+
199
+ # Reverse: .env.example → .env (generate env from template)
200
+ evnx sync --direction reverse
201
+ ```
202
+
203
+ ---
204
+
205
+ ### `evnx migrate` _(requires `--features migrate`)_
206
+
207
+ Migrates secrets directly to cloud secret managers.
208
+
209
+ ```bash
210
+ # GitHub Actions secrets
211
+ evnx migrate --from env-file --to github-actions \
212
+ --repo owner/repo --github-token $GITHUB_TOKEN
213
+
214
+ # AWS Secrets Manager
215
+ evnx migrate --to aws-secrets-manager --secret-name prod/myapp/config
216
+
217
+ # Doppler (with dry run)
218
+ evnx migrate --to doppler --dry-run
219
+ ```
220
+
221
+ ---
222
+
223
+ ### `evnx doctor`
224
+
225
+ Runs a health check on your environment configuration setup.
226
+
227
+ ```bash
228
+ evnx doctor # check current directory
229
+ evnx doctor --path /path/to/project
230
+ ```
231
+
232
+ Checks: `.env` exists and has secure permissions, `.env` is in `.gitignore`, `.env.example` is tracked by Git, and project structure detection.
233
+
234
+ ---
235
+
236
+ ### `evnx template`
237
+
238
+ Generates configuration files from templates using `.env` variable substitution.
239
+
240
+ ```bash
241
+ evnx template \
242
+ --input config.template.yml \
243
+ --output config.yml \
244
+ --env .env
245
+ ```
246
+
247
+ Supported inline filters:
248
+
249
+ ```yaml
250
+ database:
251
+ host: {{DB_HOST}}
252
+ port: {{DB_PORT|int}}
253
+ ssl: {{DB_SSL|bool}}
254
+ name: {{DB_NAME|upper}}
255
+ ```
256
+
257
+ ---
258
+
259
+ ### `evnx backup` / `evnx restore` _(requires `--features backup`)_
260
+
261
+ Creates and restores AES-256-GCM encrypted backups using Argon2 key derivation.
262
+
263
+ ```bash
264
+ evnx backup .env --output .env.backup
265
+ evnx restore .env.backup --output .env
266
+ ```
267
+
268
+ ---
269
+
270
+ ## CI/CD Integration
271
+
272
+ ### GitHub Actions
273
+
274
+ ```yaml
275
+ name: Validate environment
276
+
277
+ on: [push, pull_request]
278
+
279
+ jobs:
280
+ validate:
281
+ runs-on: ubuntu-latest
282
+ steps:
283
+ - uses: actions/checkout@v4
284
+
285
+ - name: Install evnx
286
+ run: |
287
+ curl -sSL https://raw.githubusercontent.com/urwithajit9/evnx/main/scripts/install.sh | bash
288
+
289
+ - name: Validate configuration
290
+ run: evnx validate --strict --format github-actions
291
+
292
+ - name: Scan for secrets
293
+ run: evnx scan --format sarif > scan-results.sarif
294
+
295
+ - name: Upload SARIF
296
+ uses: github/codeql-action/upload-sarif@v3
297
+ if: always()
298
+ with:
299
+ sarif_file: scan-results.sarif
300
+ ```
301
+
302
+ ### GitLab CI
303
+
304
+ ```yaml
305
+ validate-env:
306
+ stage: validate
307
+ image: alpine:latest
308
+ before_script:
309
+ - apk add --no-cache curl bash
310
+ - curl -sSL https://raw.githubusercontent.com/urwithajit9/evnx/main/scripts/install.sh | bash
311
+ script:
312
+ - evnx validate --strict --format json
313
+ - evnx scan --format sarif > scan.sarif
314
+ artifacts:
315
+ reports:
316
+ sast: scan.sarif
317
+ ```
318
+
319
+ ### Pre-commit hook
320
+
321
+ ```yaml
322
+ # .pre-commit-config.yaml
323
+ repos:
324
+ - repo: local
325
+ hooks:
326
+ - id: evnx-validate
327
+ name: Validate .env files
328
+ entry: evnx validate --strict
329
+ language: system
330
+ pass_filenames: false
331
+
332
+ - id: evnx-scan
333
+ name: Scan for secrets
334
+ entry: evnx scan --exit-zero
335
+ language: system
336
+ pass_filenames: false
337
+ ```
338
+
339
+ ---
340
+
341
+ ## Configuration
342
+
343
+ Store defaults in `.evnx.toml` at the project root:
344
+
345
+ ```toml
346
+ [defaults]
347
+ env_file = ".env"
348
+ example_file = ".env.example"
349
+ verbose = false
350
+
351
+ [validate]
352
+ strict = true
353
+ auto_fix = false
354
+ format = "pretty"
355
+
356
+ [scan]
357
+ ignore_placeholders = true
358
+ exclude_patterns = ["*.example", "*.sample", "*.template"]
359
+ format = "pretty"
360
+
361
+ [convert]
362
+ default_format = "json"
363
+ base64 = false
364
+
365
+ [aliases]
366
+ gh = "github-actions"
367
+ k8s = "kubernetes"
368
+ tf = "terraform"
369
+ ```
370
+
371
+ ---
372
+
373
+ ## Known Limitations
374
+
375
+ **Array and multiline values** — evnx follows the strict `.env` spec where values are simple strings. The following will not parse correctly:
376
+
377
+ ```bash
378
+ # Not supported
379
+ CORS_ALLOWED=["https://example.com", "https://admin.example.com"]
380
+ CONFIG={"key": "value"}
381
+ DATABASE_HOSTS="""
382
+ host1.example.com
383
+ host2.example.com
384
+ """
385
+ ```
386
+
387
+ 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).
388
+
389
+ **Windows** — file permissions checking is limited (no Unix permission model). Terminal color support requires PowerShell or Windows Terminal on older systems.
390
+
391
+ ---
392
+
393
+ ## Development
394
+
395
+ ```bash
396
+ git clone https://github.com/urwithajit9/evnx.git
397
+ cd evnx
398
+
399
+ cargo build # core features only
400
+ cargo build --all-features
401
+ cargo test
402
+ cargo clippy --all-features -- -D warnings
403
+ cargo fmt
404
+ ```
405
+
406
+ Feature flags:
407
+
408
+ ```toml
409
+ [features]
410
+ default = []
411
+ migrate = ["reqwest", "base64", "indicatif"]
412
+ backup = ["aes-gcm", "argon2", "rand"]
413
+ full = ["migrate", "backup"]
414
+ ```
415
+
416
+ ---
417
+
418
+ ## Contributing
419
+
420
+ See [CONTRIBUTING.md](CONTRIBUTING.md). Contributions are welcome in: additional format converters, secret pattern improvements, Windows enhancements, extended `.env` format support, and integration examples.
421
+
422
+ ---
423
+
424
+ ## License
425
+
426
+ MIT — see [LICENSE](LICENSE).
427
+
428
+ ---
429
+
430
+ ## Credits
431
+
432
+ Built by [Ajit Kumar](https://github.com/urwithajit9).
433
+
434
+ 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).
435
+
436
+ ---
437
+
438
+ [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.0",
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.0",
24
+ "@evnx/evnx-linux-arm64": "0.3.0",
25
+ "@evnx/evnx-darwin-x64": "0.3.0",
26
+ "@evnx/evnx-darwin-arm64": "0.3.0",
27
+ "@evnx/evnx-win32-x64": "0.3.0"
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
  }