evm-cli 2.4.0__py3-none-any.whl

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.
@@ -0,0 +1,748 @@
1
+ Metadata-Version: 2.4
2
+ Name: evm-cli
3
+ Version: 2.4.0
4
+ Summary: A command-line tool for managing environment variables
5
+ Author-email: EVM Tool <evm@example.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/zxygithub/evm
8
+ Project-URL: Repository, https://github.com/zxygithub/evm
9
+ Project-URL: Issues, https://github.com/zxygithub/evm/issues
10
+ Keywords: environment,variables,cli,devops,configuration
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: MacOS
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Topic :: System :: Systems Administration
24
+ Classifier: Topic :: Utilities
25
+ Requires-Python: >=3.9
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
30
+ Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
31
+ Requires-Dist: ruff>=0.4.0; extra == "dev"
32
+ Requires-Dist: mypy>=1.10.0; extra == "dev"
33
+ Provides-Extra: test
34
+ Requires-Dist: pytest>=8.0.0; extra == "test"
35
+ Requires-Dist: pytest-cov>=5.0.0; extra == "test"
36
+ Provides-Extra: lint
37
+ Requires-Dist: ruff>=0.4.0; extra == "lint"
38
+ Requires-Dist: mypy>=1.10.0; extra == "lint"
39
+ Dynamic: license-file
40
+
41
+ # EVM - Environment Variable Manager
42
+
43
+ A powerful command-line tool for managing environment variables on macOS and Linux systems.
44
+
45
+ **Version**: 2.4.0
46
+
47
+ ## Features
48
+
49
+ - ✅ **Set/Get/Delete**: Manage environment variables
50
+ - ✅ **List/Search**: View and find variables easily
51
+ - ✅ **Import/Export**: JSON, .env, and shell script formats
52
+ - ✅ **Backup/Restore**: Timestamps and merge support
53
+ - ✅ **Groups**: Namespace-based organization
54
+ - ✅ **Execute**: Run commands with custom environment
55
+ - ✅ **Load to Memory**: Sync variables to system environment
56
+ - ✅ **Secrets**: HKDF+HMAC-CTR encrypted storage (v3) with auto-migration from v1/v2
57
+ - ✅ **Templates**: `{{VAR}}` reference expansion
58
+ - ✅ **Diff**: Compare current state with backups
59
+ - ✅ **Dry-run**: Preview changes before writing
60
+ - ✅ **Validate**: Schema-based variable value validation (URL, email, port, etc.)
61
+ - ✅ **Schema**: Define and enforce variable formats and constraints
62
+ - ✅ **History**: Operation audit log with JSONL storage
63
+ - ✅ **Shell Completion**: bash, zsh, fish completion script generation
64
+ - ✅ **Interactive Safety**: Confirmation prompts for destructive operations (`--force` to skip)
65
+ - ✅ **JSON Output**: `--json` flag for structured output (agent-friendly, stdout=data, stderr=errors)
66
+ - ✅ **Quiet Mode**: `--quiet` suppresses all human-readable output
67
+ - ✅ **Granular Exit Codes**: 11 distinct codes for programmatic error handling
68
+ - ✅ **Secure**: Shell-safe export (key+value), chmod 600, atomic writes, shared lock file, HKDF key separation
69
+ - ✅ **Pure Python**: No external dependencies, Python 3.9+
70
+
71
+ ## Platform Support
72
+
73
+ **Supported Platforms:**
74
+ - ✅ macOS (Darwin)
75
+ - ✅ Linux (POSIX-compliant systems)
76
+ - ❌ Windows (not supported - uses `fcntl` for file locking)
77
+
78
+ **Requirements:**
79
+ - Python 3.9 or higher
80
+ - POSIX-compliant operating system (for file locking with `fcntl`)
81
+
82
+ ## Project Structure
83
+
84
+ ```
85
+ evm/
86
+ ├── evm/
87
+ │ ├── __init__.py # Package init, version info
88
+ │ ├── __main__.py # Module entry point
89
+ │ ├── cli.py # CLI parsing and command dispatch
90
+ │ ├── manager.py # Core business logic (CRUD, encryption, templates)
91
+ │ ├── _io.py # IOMixin (import/export/backup/restore/diff)
92
+ │ ├── _groups.py # GroupMixin (namespace management)
93
+ │ ├── _history.py # HistoryMixin (operation logging)
94
+ │ ├── _schema.py # SchemaMixin (format validation)
95
+ │ ├── _completion.py # Shell completion generators (bash/zsh/fish)
96
+ │ ├── _json.py # JSON output helpers (agent-friendly)
97
+ │ ├── _crypto.py # HKDF + HMAC-CTR encryption module
98
+ │ ├── formatters.py # Terminal output formatting
99
+ │ └── exceptions.py # Custom exception hierarchy (17 classes)
100
+ ├── examples/ # Example scripts
101
+ ├── tests/ # Test suite (575 tests)
102
+ │ ├── test_main.py # Unit + integration tests
103
+ │ ├── test_io_boundary.py # _io.py boundary tests
104
+ │ ├── test_cli_boundary.py # cli.py boundary tests
105
+ │ ├── test_v230_fixes.py # v2.3.0 code review fix tests
106
+ │ ├── test_coverage_gap.py # Coverage gap tests (98% target)
107
+ │ ├── test_formatters.py # Formatter output tests
108
+ │ └── test_case/ # Test configuration files
109
+ ├── docs/
110
+ │ ├── API_REFERENCE.md # Python API reference
111
+ │ ├── CHANGELOG.md # Version history
112
+ │ ├── DEVELOPMENT_REVIEW.md # Development review & roadmap
113
+ │ ├── ANALYSIS.md # Project analysis report
114
+ │ ├── USER_GUIDE_CN.md # 中文系统功能说明书
115
+ │ ├── AGENT_CLI_EVALUATION.md
116
+ │ ├── CODE_REVIEW.md
117
+ │ ├── CODE_REVIEW_v2.0.0_FINAL.md
118
+ │ └── CODE_REVIEW_v2.2.0.md
119
+ ├── skill/ # AI Agent Skill (evm-agent)
120
+ ├── pyproject.toml # PEP 621 project metadata & tool config
121
+ ├── setup.py # Backward-compatible setup shim
122
+ ├── requirements.txt # Thin wrapper pointing to pyproject.toml
123
+ ├── README.md # This file
124
+ ├── LICENSE # MIT License
125
+ └── Makefile # Build automation
126
+ ```
127
+
128
+ ## Quick Start
129
+
130
+ ### Installation
131
+
132
+ ```bash
133
+ # Core install (no third-party dependencies)
134
+ pip install .
135
+
136
+ # Development install (includes pytest, ruff, mypy)
137
+ pip install ".[dev]"
138
+
139
+ # Test-only install
140
+ pip install ".[test]"
141
+
142
+ # Lint-only install
143
+ pip install ".[lint]"
144
+
145
+ # From source (editable/development mode)
146
+ pip install -e ".[dev]"
147
+
148
+ # For current user only
149
+ pip install --user -e ".[dev]"
150
+
151
+ # Verify installation
152
+ evm --version
153
+ evm --help
154
+ ```
155
+
156
+ ### Run as Module
157
+
158
+ ```bash
159
+ python -m evm --help
160
+ ```
161
+
162
+ ### Your First 5 Minutes with EVM
163
+
164
+ **1. Basic Operations**
165
+
166
+ ```bash
167
+ # Set a variable
168
+ evm set API_KEY "abc123"
169
+
170
+ # Get the value back
171
+ evm get API_KEY
172
+ # Output: abc123
173
+
174
+ # List all variables
175
+ evm list
176
+ # Shows all stored variables in a table format
177
+ ```
178
+
179
+ **2. Use Isolated Storage (Recommended)**
180
+
181
+ By default, EVM uses `~/.evm/env.json`. For project-specific configs, use `--env-file`:
182
+
183
+ ```bash
184
+ # Create a project-specific config
185
+ evm --env-file ./project.json set DATABASE_URL "postgresql://localhost/mydb"
186
+ evm --env-file ./project.json set API_KEY "project_secret"
187
+
188
+ # Only affects this file, not your global config
189
+ evm --env-file ./project.json list
190
+ ```
191
+
192
+ **3. JSON Output for Scripts & Agents**
193
+
194
+ Use `--json` to get structured output (works before or after the command):
195
+
196
+ ```bash
197
+ # Get as JSON (both work)
198
+ evm --env-file ./project.json --json get API_KEY
199
+ evm --env-file ./project.json get API_KEY --json
200
+ # stdout: {"status": "ok", "data": {"key": "API_KEY", "value": "project_secret"}}
201
+
202
+ # List all as JSON
203
+ evm --env-file ./project.json list --json
204
+ # stdout: {"status": "ok", "data": {"API_KEY": "project_secret", "DATABASE_URL": "..."}}
205
+
206
+ # Errors go to stderr with error codes
207
+ evm --env-file ./project.json get MISSING --json
208
+ # stderr: {"status": "error", "error": "Environment variable 'MISSING' not found", "error_code": 2}
209
+ # exit code: 2
210
+ ```
211
+
212
+ **4. Preview Changes with Dry-Run**
213
+
214
+ ```bash
215
+ # Preview what would happen without actually writing
216
+ evm --env-file ./project.json set NEW_KEY "value" --dry-run
217
+ # Output: [DRY-RUN] Would set: NEW_KEY=value
218
+ # (Nothing is actually written)
219
+
220
+ # Works with delete, clear, etc.
221
+ evm --env-file ./project.json delete API_KEY --dry-run
222
+ # Output: [DRY-RUN] Would delete: API_KEY
223
+ ```
224
+
225
+ **5. Manage Multiple Environments**
226
+
227
+ Use groups to organize dev/staging/prod configurations:
228
+
229
+ ```bash
230
+ # Set variables for different environments
231
+ evm --env-file ./project.json setg dev DATABASE_URL "localhost:5432/dev"
232
+ evm --env-file ./project.json setg prod DATABASE_URL "prod.example.com:5432/prod"
233
+
234
+ # List by group
235
+ evm --env-file ./project.json listg dev
236
+ # Shows only dev group variables
237
+
238
+ # List all groups
239
+ evm --env-file ./project.json groups
240
+ # Shows: dev (1 variable), prod (1 variable)
241
+
242
+ # Export a specific environment
243
+ evm --env-file ./project.json export --group prod --format env -o .env.prod
244
+ ```
245
+
246
+ **6. Encrypt Sensitive Data**
247
+
248
+ ```bash
249
+ # Store encrypted (HKDF + HMAC-CTR encryption)
250
+ evm --env-file ./project.json set --secret DB_PASSWORD "super_secret_password"
251
+
252
+ # Retrieve decrypted
253
+ evm --env-file ./project.json get --secret DB_PASSWORD
254
+ # Output: super_secret_password
255
+ # Warning: Decrypted secret displayed on terminal (visible in scrollback).
256
+
257
+ # Note: Encryption keys are machine-bound (hostname + uid + arch)
258
+ # Secrets cannot be migrated to different machines
259
+ ```
260
+
261
+ **7. Run Commands with Environment Variables**
262
+
263
+ ```bash
264
+ # Run a command with all EVM variables injected
265
+ evm --env-file ./project.json exec -- python app.py
266
+ # Your app can access DATABASE_URL, API_KEY, etc. from os.environ
267
+
268
+ # Exit codes are passed through from the child process
269
+ evm --env-file ./project.json exec -- sh -c 'exit 42'
270
+ echo $? # Output: 42
271
+ ```
272
+
273
+ **8. Validate Configuration**
274
+
275
+ ```bash
276
+ # Define schemas for validation
277
+ evm --env-file ./project.json schema set DATABASE_URL --format url --required
278
+ evm --env-file ./project.json schema set API_KEY --pattern '^[a-zA-Z0-9]+$'
279
+
280
+ # Validate all variables
281
+ evm --env-file ./project.json validate
282
+ # Shows which variables pass/fail validation
283
+
284
+ # Validate a specific variable
285
+ evm --env-file ./project.json validate DATABASE_URL
286
+ ```
287
+
288
+ **9. Backup and Restore**
289
+
290
+ ```bash
291
+ # Create a backup
292
+ evm --env-file ./project.json backup --file backup.json
293
+
294
+ # Make some changes
295
+ evm --env-file ./project.json set NEW_VAR "value"
296
+
297
+ # Compare with backup
298
+ evm --env-file ./project.json diff backup.json
299
+ # Shows what was added/removed/changed
300
+
301
+ # Restore from backup
302
+ evm --env-file ./project.json restore backup.json
303
+ ```
304
+
305
+ **10. Quick Reference**
306
+
307
+ ```bash
308
+ # Essential flags
309
+ --env-file PATH # Use custom storage file
310
+ --json # Structured JSON output
311
+ --dry-run # Preview changes
312
+ --quiet / -q # Suppress output
313
+ --force # Skip confirmation prompts
314
+
315
+ # Common commands
316
+ evm set KEY VALUE # Set a variable
317
+ evm get KEY # Get a variable
318
+ evm list # List all variables
319
+ evm delete KEY # Delete a variable
320
+ evm setg GROUP KEY VALUE # Set in a group
321
+ evm groups # List groups
322
+ evm exec -- COMMAND # Run with env vars
323
+ evm backup # Create backup
324
+ evm validate # Check schemas
325
+ ```
326
+
327
+ ## Usage
328
+
329
+ ### Basic Commands
330
+
331
+ ```bash
332
+ # Set a variable
333
+ evm set API_KEY your_secret_key
334
+ evm set DATABASE_URL "postgresql://localhost/mydb"
335
+
336
+ # Get a variable
337
+ evm get API_KEY
338
+
339
+ # List all variables
340
+ evm list
341
+
342
+ # Delete a variable
343
+ evm delete API_KEY
344
+
345
+ # Clear all
346
+ evm clear
347
+ ```
348
+
349
+ ### Group Management
350
+
351
+ ```bash
352
+ # Set variables in groups
353
+ evm setg dev API_URL http://localhost:3000
354
+ evm setg prod API_URL https://api.example.com
355
+
356
+ # List variables in a group
357
+ evm listg dev
358
+
359
+ # List all groups
360
+ evm groups
361
+
362
+ # Show variables grouped by namespace
363
+ evm list --show-groups
364
+
365
+ # Move variable to group
366
+ evm move-group API_KEY prod
367
+
368
+ # Delete entire group
369
+ evm delete-group test
370
+ ```
371
+
372
+ ### Import/Export
373
+
374
+ ```bash
375
+ # Export to different formats
376
+ evm export --format json -o config.json
377
+ evm export --format env -o .env
378
+ evm export --format sh -o export.sh
379
+
380
+ # Import from file (auto-detects format)
381
+ evm load config.json
382
+ evm load config.env
383
+
384
+ # Import with options
385
+ evm load config.json --replace # Replace existing
386
+ evm load config.json --group dev # Add to group
387
+ evm load config.json --nest # Import nested JSON (first-level keys as groups)
388
+ ```
389
+
390
+ ### Backup & Restore
391
+
392
+ ```bash
393
+ # Create backup (auto-timestamped)
394
+ evm backup
395
+
396
+ # Backup to specific file
397
+ evm backup --file mybackup.json
398
+
399
+ # Restore
400
+ evm restore backup.json
401
+ evm restore backup.json --merge # Merge with existing
402
+ ```
403
+
404
+ ### Load to System Memory
405
+
406
+ ```bash
407
+ # Load all variables to memory (with EVM: prefix)
408
+ evm loadmemory
409
+
410
+ # Load without prefix
411
+ evm loadmemory --no-prefix
412
+
413
+ # Load with filter
414
+ evm loadmemory --prefix DEMO_
415
+
416
+ # Check in Python
417
+ python -c "import os; print(os.environ.get('EVM:API_KEY'))"
418
+ ```
419
+
420
+ ### Execute Commands
421
+
422
+ ```bash
423
+ # Run with environment variables
424
+ evm exec -- python script.py
425
+ evm exec -- npm start
426
+ ```
427
+
428
+ ### Search
429
+
430
+ ```bash
431
+ # Search by key
432
+ evm search api
433
+
434
+ # Search by key and value
435
+ evm search localhost --value
436
+ ```
437
+
438
+ ## Storage
439
+
440
+ Environment variables are stored as JSON in `~/.evm/env.json`:
441
+
442
+ ```json
443
+ {
444
+ "API_KEY": "secret123",
445
+ "dev:DATABASE_URL": "localhost:5432",
446
+ "prod:DATABASE_URL": "prod.example.com:5432"
447
+ }
448
+ ```
449
+
450
+ Use custom storage:
451
+ ```bash
452
+ evm --env-file /path/to/custom.json list
453
+ ```
454
+
455
+ ### Secrets (Encrypted Variables)
456
+
457
+ > ⚠️ **Machine-bound encryption**: Encryption keys are derived from machine identity (hostname + uid + arch). Changing hostname, migrating to another machine, or rebuilding Docker containers will make secrets unrecoverable. Use a dedicated secrets manager (Vault, AWS Secrets Manager) for cross-machine scenarios.
458
+
459
+ ```bash
460
+ # Store an encrypted secret
461
+ evm set --secret DB_PASSWORD "super_secret_password"
462
+
463
+ # Retrieve and decrypt
464
+ evm get --secret DB_PASSWORD
465
+ ```
466
+
467
+ ### Template Expansion
468
+
469
+ ```bash
470
+ # Use {{VAR}} references
471
+ evm set API_HOST "api.example.com"
472
+ evm set API_URL "https://{{API_HOST}}/v1"
473
+
474
+ # Expand templates
475
+ evm expand API_URL # → https://api.example.com/v1
476
+ ```
477
+
478
+ ### Diff
479
+
480
+ ```bash
481
+ # Compare current state with a backup
482
+ evm diff backup_20260530_120000.json
483
+ ```
484
+
485
+ ### Dry-run
486
+
487
+ ```bash
488
+ # Preview changes without writing
489
+ evm --dry-run set NEW_KEY value
490
+ evm --dry-run delete EXISTING_KEY
491
+ evm --dry-run clear
492
+ ```
493
+
494
+ ### Schema & Validate
495
+
496
+ ```bash
497
+ # Define schemas for variables
498
+ evm schema set API_URL --format url --required
499
+ evm schema set PORT --format port
500
+ evm schema set EMAIL --format email --description "Admin email"
501
+
502
+ # Available formats: url, email, port, integer, boolean, path, ipv4, ipv6
503
+ # Custom regex also supported:
504
+ evm schema set CODE --pattern '^[A-Z]{3}-\d{4}$'
505
+
506
+ # List all schemas
507
+ evm schema list
508
+
509
+ # Validate a specific variable
510
+ evm validate API_URL
511
+
512
+ # Validate all variables with schemas
513
+ evm validate
514
+
515
+ # Delete a schema
516
+ evm schema delete API_URL
517
+ ```
518
+
519
+ ### History
520
+
521
+ ```bash
522
+ # View operation history (latest first)
523
+ evm history
524
+
525
+ # Show more entries
526
+ evm history --limit 50
527
+
528
+ # Clear history
529
+ evm history --clear
530
+ ```
531
+
532
+ ### Shell Completion
533
+
534
+ ```bash
535
+ # Generate and install bash completion
536
+ evm completion bash > ~/.evm-completion.bash
537
+ echo 'source ~/.evm-completion.bash' >> ~/.bashrc
538
+
539
+ # zsh
540
+ evm completion zsh > ~/.evm-completion.zsh
541
+ echo 'source ~/.evm-completion.zsh' >> ~/.zshrc
542
+
543
+ # fish
544
+ evm completion fish > ~/.config/fish/completions/evm.fish
545
+ ```
546
+
547
+ ### Interactive Safety
548
+
549
+ ```bash
550
+ # clear and delete-group now prompt for confirmation
551
+ evm clear # Asks: "This will clear all N variables. Continue? [y/N]"
552
+ evm delete-group dev # Asks: "This will delete group 'dev'... Continue? [y/N]"
553
+
554
+ # Skip confirmation with --force
555
+ evm --force clear
556
+ evm --force delete-group dev
557
+ ```
558
+
559
+ ## Agent-Friendly Usage
560
+
561
+ EVM is designed to be easily called by AI agents and scripts:
562
+
563
+ ### JSON Output (`--json`)
564
+
565
+ All commands support structured JSON output. stdout contains data, stderr contains errors:
566
+
567
+ ```bash
568
+ # Get a variable as JSON
569
+ evm get API_KEY --json
570
+ # stdout: {"status": "ok", "data": {"key": "API_KEY", "value": "secret123"}}
571
+
572
+ # List all variables
573
+ evm list --json
574
+ # stdout: {"status": "ok", "data": {"API_KEY": "secret123", "DB_URL": "..."}}
575
+
576
+ # Errors go to stderr as JSON
577
+ evm get MISSING --json
578
+ # stderr: {"status": "error", "error": "Environment variable 'MISSING' not found", "error_code": 2}
579
+ # exit code: 2
580
+ ```
581
+
582
+ ### Quiet Mode (`--quiet` / `-q`)
583
+
584
+ Suppress all human-readable output. Combined with `--json`, only structured data on stdout:
585
+
586
+ ```bash
587
+ evm --quiet set KEY value # No output, exit code 0
588
+ evm --quiet get MISSING # No output, exit code 2
589
+ evm --json --quiet list # No stdout, only exit code
590
+ ```
591
+
592
+ ### Granular Exit Codes
593
+
594
+ | Code | Meaning | Exception Type |
595
+ |------|---------|---------------|
596
+ | 0 | Success | — |
597
+ | 1 | General error / cancelled | OperationCancelledError |
598
+ | 2 | Variable not found | KeyNotFoundError, KeyAlreadyExistsError |
599
+ | 3 | Storage error | StorageError, CorruptedStorageError, LockTimeoutError |
600
+ | 4 | Import/export format error | ImportError, ExportError |
601
+ | 5 | Decryption error | DecryptionError |
602
+ | 6 | Validation/schema error | ValidationError, SchemaError |
603
+ | 7 | Group error | GroupNotFoundError, GroupOperationError |
604
+ | 8 | Backup error | BackupError |
605
+ | 9 | Editor error | EditorError |
606
+ | 10 | Command not found | CommandNotFoundError |
607
+
608
+ ### Agent Usage Patterns
609
+
610
+ ```bash
611
+ # Read a value (parse JSON from stdout)
612
+ VALUE=$(evm get API_KEY --json | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['value'])")
613
+
614
+ # Check if variable exists
615
+ if evm get KEY --quiet 2>/dev/null; then echo "exists"; fi
616
+
617
+ # Conditional set with dry-run preview
618
+ evm --dry-run set KEY value --json # Preview without writing
619
+
620
+ # Execute with env vars (exit code is passed through)
621
+ evm exec -- python script.py
622
+ echo "Script exited with: $?"
623
+
624
+ # Use --env-file for isolated storage (no interference with user config)
625
+ evm --env-file /tmp/agent_env.json set KEY value
626
+ evm --env-file /tmp/agent_env.json --json list
627
+ ```
628
+
629
+ ## Python API
630
+
631
+ EVM can also be used as a Python library. See [**API Reference**](docs/API_REFERENCE.md) for full documentation.
632
+
633
+ ```python
634
+ from evm import EnvironmentManager, EVMError, KeyNotFoundError
635
+
636
+ manager = EnvironmentManager() # default: ~/.evm/env.json
637
+ # manager = EnvironmentManager('/path/to/env.json') # custom storage
638
+
639
+ # Basic operations
640
+ manager.set('API_KEY', 'secret123')
641
+ value = manager.get('API_KEY')
642
+ manager.set_grouped('dev', 'DEBUG', 'true')
643
+
644
+ # Encrypted secrets (HKDF+HMAC-CTR v3, auto-migration from v1/v2)
645
+ manager.set_secret('DB_PASS', 'encrypted_value')
646
+ plain = manager.get_secret('DB_PASS')
647
+
648
+ # Schema validation
649
+ manager.set_schema('API_URL', format='url', required=True)
650
+ result = manager.validate('API_URL') # {'valid': True, 'errors': [], 'warnings': []}
651
+ all_results = manager.validate_all()
652
+
653
+ # Operation history
654
+ history = manager.get_history(limit=10)
655
+
656
+ # Template expansion
657
+ manager.set('HOST', 'example.com')
658
+ manager.set('URL', 'https://{{HOST}}/api')
659
+ expanded = manager.expand('URL') # → https://example.com/api
660
+
661
+ # Import / Export / Backup
662
+ manager.load('.env')
663
+ manager.export(format_type='env', output_file='.env')
664
+ manager.backup()
665
+
666
+ # Error handling — all exceptions inherit EVMError
667
+ try:
668
+ manager.get('MISSING')
669
+ except KeyNotFoundError as e:
670
+ print(f"Not found: {e.key}")
671
+ except EVMError as e:
672
+ print(f"EVM error: {e}")
673
+ ```
674
+
675
+ ## Development
676
+
677
+ ```bash
678
+ # Install for development (includes pytest, ruff, mypy)
679
+ pip install -e ".[dev]"
680
+
681
+ # Run tests
682
+ python -m pytest tests/ -v
683
+
684
+ # Run tests with coverage
685
+ python -m pytest tests/ --cov=evm --cov-report=term-missing
686
+
687
+ # Lint with ruff
688
+ ruff check evm/ tests/
689
+
690
+ # Auto-fix lint issues
691
+ ruff check --fix evm/ tests/
692
+
693
+ # Type check with mypy
694
+ mypy evm/
695
+
696
+ # Run demo
697
+ make demo
698
+ ```
699
+
700
+ ## Examples
701
+
702
+ ### Development Workflow
703
+
704
+ ```bash
705
+ # Setup dev environment
706
+ evm setg dev NODE_ENV development
707
+ evm setg dev API_URL http://localhost:3000
708
+ evm setg dev DEBUG true
709
+
710
+ # Export for team
711
+ evm export --format env -o .env
712
+
713
+ # Run application
714
+ evm exec -- npm start
715
+ ```
716
+
717
+ ### Multi-Environment Management
718
+
719
+ ```bash
720
+ # Setup environments
721
+ evm setg dev DATABASE_URL "localhost:5432/dev"
722
+ evm setg test DATABASE_URL "test-server:5432/test"
723
+ evm setg prod DATABASE_URL "prod-server:5432/prod"
724
+
725
+ # View all
726
+ evm list --show-groups
727
+
728
+ # Export specific environment
729
+ evm listg dev
730
+ evm export --group dev --format env
731
+ ```
732
+
733
+ ## Requirements
734
+
735
+ - **Python 3.9+**
736
+ - **No external dependencies** (uses only standard library)
737
+
738
+ ## License
739
+
740
+ MIT License
741
+
742
+ ## Contributing
743
+
744
+ Contributions are welcome! Please feel free to submit a Pull Request.
745
+
746
+ ## Support
747
+
748
+ For issues and questions, please open an issue on GitHub.