envlockr 1.0.0__tar.gz

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.
envlockr-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Rohan Ratwani
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,241 @@
1
+ Metadata-Version: 2.4
2
+ Name: envlockr
3
+ Version: 1.0.0
4
+ Summary: Secure your environment variables — locally, encrypted, and stream-safe.
5
+ Author-email: Rohan Ratwani <rohanratwani@example.com>
6
+ Maintainer-email: Rohan Ratwani <rohanratwani@example.com>
7
+ License: MIT
8
+ Project-URL: Homepage, https://envlockr.netlify.app
9
+ Project-URL: Documentation, https://github.com/RohanRatwani/envlockr-cli#readme
10
+ Project-URL: Repository, https://github.com/RohanRatwani/envlockr-cli
11
+ Project-URL: Issues, https://github.com/RohanRatwani/envlockr-cli/issues
12
+ Project-URL: Changelog, https://github.com/RohanRatwani/envlockr-cli/blob/main/CHANGELOG.md
13
+ Keywords: environment-variables,secrets,encryption,security,cli,env,dotenv,secrets-management,local-first,developer-tools
14
+ Classifier: Development Status :: 5 - Production/Stable
15
+ Classifier: Environment :: Console
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.7
21
+ Classifier: Programming Language :: Python :: 3.8
22
+ Classifier: Programming Language :: Python :: 3.9
23
+ Classifier: Programming Language :: Python :: 3.10
24
+ Classifier: Programming Language :: Python :: 3.11
25
+ Classifier: Programming Language :: Python :: 3.12
26
+ Classifier: Topic :: Security
27
+ Classifier: Topic :: Security :: Cryptography
28
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
29
+ Classifier: Topic :: Utilities
30
+ Requires-Python: >=3.7
31
+ Description-Content-Type: text/markdown
32
+ License-File: LICENSE
33
+ Requires-Dist: cryptography>=3.4.0
34
+ Provides-Extra: clipboard
35
+ Requires-Dist: pyperclip>=1.8.0; extra == "clipboard"
36
+ Provides-Extra: dev
37
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
38
+ Requires-Dist: black>=22.0.0; extra == "dev"
39
+ Requires-Dist: flake8>=4.0.0; extra == "dev"
40
+ Dynamic: license-file
41
+
42
+ <p align="center">
43
+ <img src="banner.png" alt="EnvLockr - Secure Your Environment Variables Locally" />
44
+ </p>
45
+
46
+ # 🔐 EnvLockr CLI
47
+
48
+ [![PyPI version](https://badge.fury.io/py/envlockr.svg)](https://pypi.org/project/envlockr/)
49
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
50
+ [![Python 3.7+](https://img.shields.io/badge/python-3.7+-blue.svg)](https://www.python.org/downloads/)
51
+ [![GitHub stars](https://img.shields.io/github/stars/RohanRatwani/envlockr-cli?style=social)](https://github.com/RohanRatwani/envlockr-cli/stargazers)
52
+
53
+ > Secure your environment variables — locally, encrypted, and stream-safe.
54
+
55
+ EnvLockr CLI is a tool for developers, streamers, and indie hackers who want full control of their secrets without relying on cloud services.
56
+
57
+ ## ✨ Features
58
+
59
+ - **Local-first**: All secrets stored securely on your machine
60
+ - **AES Encryption**: Protects your secrets even if your disk is compromised
61
+ - **Offline Mode**: No internet needed to operate
62
+ - **Stream-Safe**: No .env file leaks on screen while coding or streaming
63
+ - **Simple CLI**: Add, copy, list, and retrieve secrets instantly
64
+ - **Cross-Project Friendly**: Works with React, Node.js, Python, and more
65
+ - **GitHub Action**: Automatically scan commits for exposed secrets ([Learn more](GITHUB_ACTION.md))
66
+
67
+ ## 🚀 Quick Start
68
+
69
+ ### 1. Install
70
+
71
+ ```bash
72
+ # Install from PyPI (recommended)
73
+ pip install envlockr
74
+
75
+ # With clipboard support
76
+ pip install envlockr[clipboard]
77
+ ```
78
+
79
+ <details>
80
+ <summary>Alternative: Install from source</summary>
81
+
82
+ ```bash
83
+ git clone https://github.com/RohanRatwani/envlockr-cli.git
84
+ cd envlockr-cli
85
+ pip install -e .
86
+ ```
87
+ </details>
88
+
89
+ ### 2. Commands
90
+
91
+ | Command | Example | What it Does |
92
+ |---------|---------|-------------|
93
+ | add | `envlockr add STRIPE_KEY` | Add a new secret |
94
+ | get | `envlockr get STRIPE_KEY` | Retrieve a secret |
95
+ | list | `envlockr list` | List all stored secrets |
96
+ | copy | `envlockr copy STRIPE_KEY` | Copy secret to clipboard |
97
+ | update | `envlockr update STRIPE_KEY` | Update an existing secret |
98
+ | delete | `envlockr delete STRIPE_KEY` | Delete a secret |
99
+ | export | `envlockr export --output .env` | Export all secrets to .env file |
100
+ | import | `envlockr import .env` | Import secrets from .env file |
101
+ | --version | `envlockr --version` | Show version number |
102
+ ## ⚡ How to Use in Your Projects
103
+
104
+ ### 🖥 Node.js / React / Vite / Next.js
105
+
106
+ #### Option 1: Export to .env file
107
+
108
+ ```bash
109
+ envlockr export --output .env
110
+ npm run dev
111
+ ```
112
+
113
+ #### Option 2: Inline Injection (no .env needed)
114
+
115
+ ```bash
116
+ export STRIPE_KEY=$(envlockr get STRIPE_KEY)
117
+ npm run dev
118
+ ```
119
+
120
+ #### Option 3: Import existing .env file
121
+
122
+ ```bash
123
+ # Migrate your existing .env to encrypted storage
124
+ envlockr import .env
125
+ rm .env # Delete the unencrypted file
126
+ ```
127
+
128
+ ### 🛠 Compatible with
129
+
130
+ - create-react-app
131
+ - Next.js
132
+ - Vite
133
+ - Remix
134
+ - Express
135
+ - NestJS
136
+ - and more!
137
+
138
+ 👉 **[See framework-specific examples](EXAMPLES.md)** - React, Next.js, Python, Docker, and more!
139
+
140
+ ## 📦 Local Storage
141
+
142
+ All your secrets are encrypted and stored in:
143
+
144
+ ```
145
+ ~/.envlockr/vault.json
146
+ ~/.envlockr/key.key
147
+ ```
148
+
149
+ - ✅ AES-256 level security
150
+ - ✅ No external cloud or server dependency
151
+
152
+ ## � GitHub Action - Prevent Secret Leaks
153
+
154
+ EnvLockr includes a **GitHub Action** that automatically scans your repository for exposed secrets!
155
+
156
+ ### Quick Setup
157
+
158
+ Add this to `.github/workflows/envlockr-scan.yml`:
159
+
160
+ ```yaml
161
+ name: EnvLockr Secret Scan
162
+ on: [pull_request, push]
163
+
164
+ jobs:
165
+ scan:
166
+ runs-on: ubuntu-latest
167
+ steps:
168
+ - uses: actions/checkout@v4
169
+ - name: Scan for secrets
170
+ run: |
171
+ curl -sSL https://raw.githubusercontent.com/RohanRatwani/envlockr-cli/main/.github/scripts/scan-secrets.sh | bash
172
+ ```
173
+
174
+ **What it does:**
175
+ - ✅ Scans commits for API keys, tokens, and passwords
176
+ - ✅ Blocks PRs if secrets are detected
177
+ - ✅ Posts helpful comments with fix instructions
178
+ - ✅ Detects AWS, Stripe, GitHub, Google, OpenAI, and more
179
+
180
+ 👉 [Full GitHub Action Documentation](GITHUB_ACTION.md)
181
+
182
+ ## Why EnvLockr?
183
+
184
+ - 🔒 **Protect your keys** without trusting the cloud
185
+ - 🎥 **Stream coding sessions** without leaking environment secrets
186
+ - ⚡ **Speed up local development** with simple, fast secret management
187
+
188
+ ## 📚 Documentation
189
+
190
+ - **[Quick Reference Guide](QUICKSTART.md)** - Common commands and workflows
191
+ - **[Framework Examples](EXAMPLES.md)** - React, Next.js, Python, Node.js, Docker
192
+ - **[GitHub Action Setup](GITHUB_ACTION.md)** - Prevent secret leaks in CI/CD
193
+ - **[Contributing Guide](CONTRIBUTING.md)** - Help improve EnvLockr
194
+ - **[Changelog](CHANGELOG.md)** - Version history
195
+
196
+ ## ☕ Support the Project
197
+
198
+ If EnvLockr helps you, consider supporting its development:
199
+
200
+ <a href="https://www.buymeacoffee.com/rohanratwani" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 40px !important;width: 145px !important;" ></a>
201
+
202
+ Or [become a GitHub Sponsor](https://github.com/sponsors/RohanRatwani)
203
+
204
+ ## 📥 What's Next?
205
+
206
+ We're exploring new features for EnvLockr, including:
207
+ - Advanced environment injection
208
+ - Project-specific vaults
209
+ - Desktop UI app
210
+ - IDE integrations (VS Code, JetBrains)
211
+ - Team collaboration features
212
+
213
+ 👉 [Join the Waitlist](https://envlockr.netlify.app/) and share your thoughts!
214
+
215
+ ## 💡 We Want Your Feedback!
216
+
217
+ Which features would you love to see in EnvLockr?
218
+ - 💬 [GitHub Discussions](https://github.com/RohanRatwani/envlockr-cli/discussions)
219
+ - 🐛 [Report Issues](https://github.com/RohanRatwani/envlockr-cli/issues)
220
+ - 🌟 [Star us on GitHub](https://github.com/RohanRatwani/envlockr-cli)
221
+
222
+ ## 📚 Documentation
223
+
224
+ - [Quick Reference Guide](QUICKSTART.md) - Common commands and workflows
225
+ - [GitHub Action Setup](GITHUB_ACTION.md) - Prevent secret leaks in CI/CD
226
+ - [Contributing Guide](CONTRIBUTING.md) - Help improve EnvLockr
227
+ - [Changelog](CHANGELOG.md) - Version history
228
+
229
+ ## 🛡 License
230
+
231
+ This project is licensed under the [MIT License](LICENSE).
232
+
233
+ ---
234
+
235
+ <p align="center">
236
+ Made with ❤️ by <a href="https://github.com/RohanRatwani">Rohan Ratwani</a>
237
+ <br>
238
+ <a href="https://envlockr.netlify.app">Website</a> ·
239
+ <a href="https://github.com/RohanRatwani/envlockr-cli">GitHub</a> ·
240
+ <a href="https://twitter.com/envlockr">Twitter</a>
241
+ </p>
@@ -0,0 +1,200 @@
1
+ <p align="center">
2
+ <img src="banner.png" alt="EnvLockr - Secure Your Environment Variables Locally" />
3
+ </p>
4
+
5
+ # 🔐 EnvLockr CLI
6
+
7
+ [![PyPI version](https://badge.fury.io/py/envlockr.svg)](https://pypi.org/project/envlockr/)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+ [![Python 3.7+](https://img.shields.io/badge/python-3.7+-blue.svg)](https://www.python.org/downloads/)
10
+ [![GitHub stars](https://img.shields.io/github/stars/RohanRatwani/envlockr-cli?style=social)](https://github.com/RohanRatwani/envlockr-cli/stargazers)
11
+
12
+ > Secure your environment variables — locally, encrypted, and stream-safe.
13
+
14
+ EnvLockr CLI is a tool for developers, streamers, and indie hackers who want full control of their secrets without relying on cloud services.
15
+
16
+ ## ✨ Features
17
+
18
+ - **Local-first**: All secrets stored securely on your machine
19
+ - **AES Encryption**: Protects your secrets even if your disk is compromised
20
+ - **Offline Mode**: No internet needed to operate
21
+ - **Stream-Safe**: No .env file leaks on screen while coding or streaming
22
+ - **Simple CLI**: Add, copy, list, and retrieve secrets instantly
23
+ - **Cross-Project Friendly**: Works with React, Node.js, Python, and more
24
+ - **GitHub Action**: Automatically scan commits for exposed secrets ([Learn more](GITHUB_ACTION.md))
25
+
26
+ ## 🚀 Quick Start
27
+
28
+ ### 1. Install
29
+
30
+ ```bash
31
+ # Install from PyPI (recommended)
32
+ pip install envlockr
33
+
34
+ # With clipboard support
35
+ pip install envlockr[clipboard]
36
+ ```
37
+
38
+ <details>
39
+ <summary>Alternative: Install from source</summary>
40
+
41
+ ```bash
42
+ git clone https://github.com/RohanRatwani/envlockr-cli.git
43
+ cd envlockr-cli
44
+ pip install -e .
45
+ ```
46
+ </details>
47
+
48
+ ### 2. Commands
49
+
50
+ | Command | Example | What it Does |
51
+ |---------|---------|-------------|
52
+ | add | `envlockr add STRIPE_KEY` | Add a new secret |
53
+ | get | `envlockr get STRIPE_KEY` | Retrieve a secret |
54
+ | list | `envlockr list` | List all stored secrets |
55
+ | copy | `envlockr copy STRIPE_KEY` | Copy secret to clipboard |
56
+ | update | `envlockr update STRIPE_KEY` | Update an existing secret |
57
+ | delete | `envlockr delete STRIPE_KEY` | Delete a secret |
58
+ | export | `envlockr export --output .env` | Export all secrets to .env file |
59
+ | import | `envlockr import .env` | Import secrets from .env file |
60
+ | --version | `envlockr --version` | Show version number |
61
+ ## ⚡ How to Use in Your Projects
62
+
63
+ ### 🖥 Node.js / React / Vite / Next.js
64
+
65
+ #### Option 1: Export to .env file
66
+
67
+ ```bash
68
+ envlockr export --output .env
69
+ npm run dev
70
+ ```
71
+
72
+ #### Option 2: Inline Injection (no .env needed)
73
+
74
+ ```bash
75
+ export STRIPE_KEY=$(envlockr get STRIPE_KEY)
76
+ npm run dev
77
+ ```
78
+
79
+ #### Option 3: Import existing .env file
80
+
81
+ ```bash
82
+ # Migrate your existing .env to encrypted storage
83
+ envlockr import .env
84
+ rm .env # Delete the unencrypted file
85
+ ```
86
+
87
+ ### 🛠 Compatible with
88
+
89
+ - create-react-app
90
+ - Next.js
91
+ - Vite
92
+ - Remix
93
+ - Express
94
+ - NestJS
95
+ - and more!
96
+
97
+ 👉 **[See framework-specific examples](EXAMPLES.md)** - React, Next.js, Python, Docker, and more!
98
+
99
+ ## 📦 Local Storage
100
+
101
+ All your secrets are encrypted and stored in:
102
+
103
+ ```
104
+ ~/.envlockr/vault.json
105
+ ~/.envlockr/key.key
106
+ ```
107
+
108
+ - ✅ AES-256 level security
109
+ - ✅ No external cloud or server dependency
110
+
111
+ ## � GitHub Action - Prevent Secret Leaks
112
+
113
+ EnvLockr includes a **GitHub Action** that automatically scans your repository for exposed secrets!
114
+
115
+ ### Quick Setup
116
+
117
+ Add this to `.github/workflows/envlockr-scan.yml`:
118
+
119
+ ```yaml
120
+ name: EnvLockr Secret Scan
121
+ on: [pull_request, push]
122
+
123
+ jobs:
124
+ scan:
125
+ runs-on: ubuntu-latest
126
+ steps:
127
+ - uses: actions/checkout@v4
128
+ - name: Scan for secrets
129
+ run: |
130
+ curl -sSL https://raw.githubusercontent.com/RohanRatwani/envlockr-cli/main/.github/scripts/scan-secrets.sh | bash
131
+ ```
132
+
133
+ **What it does:**
134
+ - ✅ Scans commits for API keys, tokens, and passwords
135
+ - ✅ Blocks PRs if secrets are detected
136
+ - ✅ Posts helpful comments with fix instructions
137
+ - ✅ Detects AWS, Stripe, GitHub, Google, OpenAI, and more
138
+
139
+ 👉 [Full GitHub Action Documentation](GITHUB_ACTION.md)
140
+
141
+ ## Why EnvLockr?
142
+
143
+ - 🔒 **Protect your keys** without trusting the cloud
144
+ - 🎥 **Stream coding sessions** without leaking environment secrets
145
+ - ⚡ **Speed up local development** with simple, fast secret management
146
+
147
+ ## 📚 Documentation
148
+
149
+ - **[Quick Reference Guide](QUICKSTART.md)** - Common commands and workflows
150
+ - **[Framework Examples](EXAMPLES.md)** - React, Next.js, Python, Node.js, Docker
151
+ - **[GitHub Action Setup](GITHUB_ACTION.md)** - Prevent secret leaks in CI/CD
152
+ - **[Contributing Guide](CONTRIBUTING.md)** - Help improve EnvLockr
153
+ - **[Changelog](CHANGELOG.md)** - Version history
154
+
155
+ ## ☕ Support the Project
156
+
157
+ If EnvLockr helps you, consider supporting its development:
158
+
159
+ <a href="https://www.buymeacoffee.com/rohanratwani" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 40px !important;width: 145px !important;" ></a>
160
+
161
+ Or [become a GitHub Sponsor](https://github.com/sponsors/RohanRatwani)
162
+
163
+ ## 📥 What's Next?
164
+
165
+ We're exploring new features for EnvLockr, including:
166
+ - Advanced environment injection
167
+ - Project-specific vaults
168
+ - Desktop UI app
169
+ - IDE integrations (VS Code, JetBrains)
170
+ - Team collaboration features
171
+
172
+ 👉 [Join the Waitlist](https://envlockr.netlify.app/) and share your thoughts!
173
+
174
+ ## 💡 We Want Your Feedback!
175
+
176
+ Which features would you love to see in EnvLockr?
177
+ - 💬 [GitHub Discussions](https://github.com/RohanRatwani/envlockr-cli/discussions)
178
+ - 🐛 [Report Issues](https://github.com/RohanRatwani/envlockr-cli/issues)
179
+ - 🌟 [Star us on GitHub](https://github.com/RohanRatwani/envlockr-cli)
180
+
181
+ ## 📚 Documentation
182
+
183
+ - [Quick Reference Guide](QUICKSTART.md) - Common commands and workflows
184
+ - [GitHub Action Setup](GITHUB_ACTION.md) - Prevent secret leaks in CI/CD
185
+ - [Contributing Guide](CONTRIBUTING.md) - Help improve EnvLockr
186
+ - [Changelog](CHANGELOG.md) - Version history
187
+
188
+ ## 🛡 License
189
+
190
+ This project is licensed under the [MIT License](LICENSE).
191
+
192
+ ---
193
+
194
+ <p align="center">
195
+ Made with ❤️ by <a href="https://github.com/RohanRatwani">Rohan Ratwani</a>
196
+ <br>
197
+ <a href="https://envlockr.netlify.app">Website</a> ·
198
+ <a href="https://github.com/RohanRatwani/envlockr-cli">GitHub</a> ·
199
+ <a href="https://twitter.com/envlockr">Twitter</a>
200
+ </p>
@@ -0,0 +1,241 @@
1
+ Metadata-Version: 2.4
2
+ Name: envlockr
3
+ Version: 1.0.0
4
+ Summary: Secure your environment variables — locally, encrypted, and stream-safe.
5
+ Author-email: Rohan Ratwani <rohanratwani@example.com>
6
+ Maintainer-email: Rohan Ratwani <rohanratwani@example.com>
7
+ License: MIT
8
+ Project-URL: Homepage, https://envlockr.netlify.app
9
+ Project-URL: Documentation, https://github.com/RohanRatwani/envlockr-cli#readme
10
+ Project-URL: Repository, https://github.com/RohanRatwani/envlockr-cli
11
+ Project-URL: Issues, https://github.com/RohanRatwani/envlockr-cli/issues
12
+ Project-URL: Changelog, https://github.com/RohanRatwani/envlockr-cli/blob/main/CHANGELOG.md
13
+ Keywords: environment-variables,secrets,encryption,security,cli,env,dotenv,secrets-management,local-first,developer-tools
14
+ Classifier: Development Status :: 5 - Production/Stable
15
+ Classifier: Environment :: Console
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.7
21
+ Classifier: Programming Language :: Python :: 3.8
22
+ Classifier: Programming Language :: Python :: 3.9
23
+ Classifier: Programming Language :: Python :: 3.10
24
+ Classifier: Programming Language :: Python :: 3.11
25
+ Classifier: Programming Language :: Python :: 3.12
26
+ Classifier: Topic :: Security
27
+ Classifier: Topic :: Security :: Cryptography
28
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
29
+ Classifier: Topic :: Utilities
30
+ Requires-Python: >=3.7
31
+ Description-Content-Type: text/markdown
32
+ License-File: LICENSE
33
+ Requires-Dist: cryptography>=3.4.0
34
+ Provides-Extra: clipboard
35
+ Requires-Dist: pyperclip>=1.8.0; extra == "clipboard"
36
+ Provides-Extra: dev
37
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
38
+ Requires-Dist: black>=22.0.0; extra == "dev"
39
+ Requires-Dist: flake8>=4.0.0; extra == "dev"
40
+ Dynamic: license-file
41
+
42
+ <p align="center">
43
+ <img src="banner.png" alt="EnvLockr - Secure Your Environment Variables Locally" />
44
+ </p>
45
+
46
+ # 🔐 EnvLockr CLI
47
+
48
+ [![PyPI version](https://badge.fury.io/py/envlockr.svg)](https://pypi.org/project/envlockr/)
49
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
50
+ [![Python 3.7+](https://img.shields.io/badge/python-3.7+-blue.svg)](https://www.python.org/downloads/)
51
+ [![GitHub stars](https://img.shields.io/github/stars/RohanRatwani/envlockr-cli?style=social)](https://github.com/RohanRatwani/envlockr-cli/stargazers)
52
+
53
+ > Secure your environment variables — locally, encrypted, and stream-safe.
54
+
55
+ EnvLockr CLI is a tool for developers, streamers, and indie hackers who want full control of their secrets without relying on cloud services.
56
+
57
+ ## ✨ Features
58
+
59
+ - **Local-first**: All secrets stored securely on your machine
60
+ - **AES Encryption**: Protects your secrets even if your disk is compromised
61
+ - **Offline Mode**: No internet needed to operate
62
+ - **Stream-Safe**: No .env file leaks on screen while coding or streaming
63
+ - **Simple CLI**: Add, copy, list, and retrieve secrets instantly
64
+ - **Cross-Project Friendly**: Works with React, Node.js, Python, and more
65
+ - **GitHub Action**: Automatically scan commits for exposed secrets ([Learn more](GITHUB_ACTION.md))
66
+
67
+ ## 🚀 Quick Start
68
+
69
+ ### 1. Install
70
+
71
+ ```bash
72
+ # Install from PyPI (recommended)
73
+ pip install envlockr
74
+
75
+ # With clipboard support
76
+ pip install envlockr[clipboard]
77
+ ```
78
+
79
+ <details>
80
+ <summary>Alternative: Install from source</summary>
81
+
82
+ ```bash
83
+ git clone https://github.com/RohanRatwani/envlockr-cli.git
84
+ cd envlockr-cli
85
+ pip install -e .
86
+ ```
87
+ </details>
88
+
89
+ ### 2. Commands
90
+
91
+ | Command | Example | What it Does |
92
+ |---------|---------|-------------|
93
+ | add | `envlockr add STRIPE_KEY` | Add a new secret |
94
+ | get | `envlockr get STRIPE_KEY` | Retrieve a secret |
95
+ | list | `envlockr list` | List all stored secrets |
96
+ | copy | `envlockr copy STRIPE_KEY` | Copy secret to clipboard |
97
+ | update | `envlockr update STRIPE_KEY` | Update an existing secret |
98
+ | delete | `envlockr delete STRIPE_KEY` | Delete a secret |
99
+ | export | `envlockr export --output .env` | Export all secrets to .env file |
100
+ | import | `envlockr import .env` | Import secrets from .env file |
101
+ | --version | `envlockr --version` | Show version number |
102
+ ## ⚡ How to Use in Your Projects
103
+
104
+ ### 🖥 Node.js / React / Vite / Next.js
105
+
106
+ #### Option 1: Export to .env file
107
+
108
+ ```bash
109
+ envlockr export --output .env
110
+ npm run dev
111
+ ```
112
+
113
+ #### Option 2: Inline Injection (no .env needed)
114
+
115
+ ```bash
116
+ export STRIPE_KEY=$(envlockr get STRIPE_KEY)
117
+ npm run dev
118
+ ```
119
+
120
+ #### Option 3: Import existing .env file
121
+
122
+ ```bash
123
+ # Migrate your existing .env to encrypted storage
124
+ envlockr import .env
125
+ rm .env # Delete the unencrypted file
126
+ ```
127
+
128
+ ### 🛠 Compatible with
129
+
130
+ - create-react-app
131
+ - Next.js
132
+ - Vite
133
+ - Remix
134
+ - Express
135
+ - NestJS
136
+ - and more!
137
+
138
+ 👉 **[See framework-specific examples](EXAMPLES.md)** - React, Next.js, Python, Docker, and more!
139
+
140
+ ## 📦 Local Storage
141
+
142
+ All your secrets are encrypted and stored in:
143
+
144
+ ```
145
+ ~/.envlockr/vault.json
146
+ ~/.envlockr/key.key
147
+ ```
148
+
149
+ - ✅ AES-256 level security
150
+ - ✅ No external cloud or server dependency
151
+
152
+ ## � GitHub Action - Prevent Secret Leaks
153
+
154
+ EnvLockr includes a **GitHub Action** that automatically scans your repository for exposed secrets!
155
+
156
+ ### Quick Setup
157
+
158
+ Add this to `.github/workflows/envlockr-scan.yml`:
159
+
160
+ ```yaml
161
+ name: EnvLockr Secret Scan
162
+ on: [pull_request, push]
163
+
164
+ jobs:
165
+ scan:
166
+ runs-on: ubuntu-latest
167
+ steps:
168
+ - uses: actions/checkout@v4
169
+ - name: Scan for secrets
170
+ run: |
171
+ curl -sSL https://raw.githubusercontent.com/RohanRatwani/envlockr-cli/main/.github/scripts/scan-secrets.sh | bash
172
+ ```
173
+
174
+ **What it does:**
175
+ - ✅ Scans commits for API keys, tokens, and passwords
176
+ - ✅ Blocks PRs if secrets are detected
177
+ - ✅ Posts helpful comments with fix instructions
178
+ - ✅ Detects AWS, Stripe, GitHub, Google, OpenAI, and more
179
+
180
+ 👉 [Full GitHub Action Documentation](GITHUB_ACTION.md)
181
+
182
+ ## Why EnvLockr?
183
+
184
+ - 🔒 **Protect your keys** without trusting the cloud
185
+ - 🎥 **Stream coding sessions** without leaking environment secrets
186
+ - ⚡ **Speed up local development** with simple, fast secret management
187
+
188
+ ## 📚 Documentation
189
+
190
+ - **[Quick Reference Guide](QUICKSTART.md)** - Common commands and workflows
191
+ - **[Framework Examples](EXAMPLES.md)** - React, Next.js, Python, Node.js, Docker
192
+ - **[GitHub Action Setup](GITHUB_ACTION.md)** - Prevent secret leaks in CI/CD
193
+ - **[Contributing Guide](CONTRIBUTING.md)** - Help improve EnvLockr
194
+ - **[Changelog](CHANGELOG.md)** - Version history
195
+
196
+ ## ☕ Support the Project
197
+
198
+ If EnvLockr helps you, consider supporting its development:
199
+
200
+ <a href="https://www.buymeacoffee.com/rohanratwani" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 40px !important;width: 145px !important;" ></a>
201
+
202
+ Or [become a GitHub Sponsor](https://github.com/sponsors/RohanRatwani)
203
+
204
+ ## 📥 What's Next?
205
+
206
+ We're exploring new features for EnvLockr, including:
207
+ - Advanced environment injection
208
+ - Project-specific vaults
209
+ - Desktop UI app
210
+ - IDE integrations (VS Code, JetBrains)
211
+ - Team collaboration features
212
+
213
+ 👉 [Join the Waitlist](https://envlockr.netlify.app/) and share your thoughts!
214
+
215
+ ## 💡 We Want Your Feedback!
216
+
217
+ Which features would you love to see in EnvLockr?
218
+ - 💬 [GitHub Discussions](https://github.com/RohanRatwani/envlockr-cli/discussions)
219
+ - 🐛 [Report Issues](https://github.com/RohanRatwani/envlockr-cli/issues)
220
+ - 🌟 [Star us on GitHub](https://github.com/RohanRatwani/envlockr-cli)
221
+
222
+ ## 📚 Documentation
223
+
224
+ - [Quick Reference Guide](QUICKSTART.md) - Common commands and workflows
225
+ - [GitHub Action Setup](GITHUB_ACTION.md) - Prevent secret leaks in CI/CD
226
+ - [Contributing Guide](CONTRIBUTING.md) - Help improve EnvLockr
227
+ - [Changelog](CHANGELOG.md) - Version history
228
+
229
+ ## 🛡 License
230
+
231
+ This project is licensed under the [MIT License](LICENSE).
232
+
233
+ ---
234
+
235
+ <p align="center">
236
+ Made with ❤️ by <a href="https://github.com/RohanRatwani">Rohan Ratwani</a>
237
+ <br>
238
+ <a href="https://envlockr.netlify.app">Website</a> ·
239
+ <a href="https://github.com/RohanRatwani/envlockr-cli">GitHub</a> ·
240
+ <a href="https://twitter.com/envlockr">Twitter</a>
241
+ </p>
@@ -0,0 +1,10 @@
1
+ LICENSE
2
+ README.md
3
+ envlockr.py
4
+ pyproject.toml
5
+ envlockr.egg-info/PKG-INFO
6
+ envlockr.egg-info/SOURCES.txt
7
+ envlockr.egg-info/dependency_links.txt
8
+ envlockr.egg-info/entry_points.txt
9
+ envlockr.egg-info/requires.txt
10
+ envlockr.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ envlockr = envlockr:main
@@ -0,0 +1,9 @@
1
+ cryptography>=3.4.0
2
+
3
+ [clipboard]
4
+ pyperclip>=1.8.0
5
+
6
+ [dev]
7
+ pytest>=7.0.0
8
+ black>=22.0.0
9
+ flake8>=4.0.0
@@ -0,0 +1 @@
1
+ envlockr
@@ -0,0 +1,504 @@
1
+ import argparse
2
+ import getpass
3
+ import json
4
+ import os
5
+ import stat
6
+ import sys
7
+
8
+ # Version
9
+ __version__ = "1.0.0"
10
+
11
+ # Try to import optional dependencies
12
+ pyperclip = None # type: ignore
13
+ try:
14
+ import pyperclip
15
+ PYPERCLIP_AVAILABLE = True
16
+ except ImportError:
17
+ PYPERCLIP_AVAILABLE = False
18
+
19
+ try:
20
+ from cryptography.fernet import Fernet, InvalidToken
21
+ except ImportError:
22
+ print("❌ Error: 'cryptography' package is required.")
23
+ print(" Install it with: pip install cryptography")
24
+ sys.exit(1)
25
+
26
+ # Constants
27
+ VAULT_DIR = os.path.expanduser("~/.envlockr")
28
+ VAULT_FILE = os.path.join(VAULT_DIR, "vault.json")
29
+ KEY_FILE = os.path.join(VAULT_DIR, "key.key")
30
+
31
+ # Color support
32
+ class Colors:
33
+ """ANSI color codes for terminal output"""
34
+ RED = '\033[0;31m'
35
+ GREEN = '\033[0;32m'
36
+ YELLOW = '\033[1;33m'
37
+ BLUE = '\033[0;34m'
38
+ CYAN = '\033[0;36m'
39
+ BOLD = '\033[1m'
40
+ NC = '\033[0m' # No Color
41
+
42
+ @classmethod
43
+ def disable(cls):
44
+ """Disable colors (for non-TTY or Windows without color support)"""
45
+ cls.RED = cls.GREEN = cls.YELLOW = cls.BLUE = cls.CYAN = cls.BOLD = cls.NC = ''
46
+
47
+ # Disable colors if not a TTY or on Windows without proper support
48
+ if not sys.stdout.isatty():
49
+ Colors.disable()
50
+ elif sys.platform == 'win32':
51
+ try:
52
+ # Enable ANSI colors on Windows 10+
53
+ import ctypes
54
+ kernel32 = ctypes.windll.kernel32
55
+ kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
56
+ except Exception:
57
+ Colors.disable()
58
+
59
+
60
+ def print_success(message):
61
+ """Print success message in green"""
62
+ print(f"{Colors.GREEN}✅ {message}{Colors.NC}")
63
+
64
+
65
+ def print_error(message):
66
+ """Print error message in red"""
67
+ print(f"{Colors.RED}❌ {message}{Colors.NC}")
68
+
69
+
70
+ def print_warning(message):
71
+ """Print warning message in yellow"""
72
+ print(f"{Colors.YELLOW}⚠️ {message}{Colors.NC}")
73
+
74
+
75
+ def print_info(message):
76
+ """Print info message in blue"""
77
+ print(f"{Colors.BLUE}ℹ️ {message}{Colors.NC}")
78
+
79
+
80
+ # Ensure the ~/.envlockr directory exists
81
+ def ensure_vault_dir():
82
+ """Create vault directory with secure permissions"""
83
+ if not os.path.exists(VAULT_DIR):
84
+ os.makedirs(VAULT_DIR, mode=0o700)
85
+
86
+
87
+ def check_key_file_security():
88
+ """Warn if key file has insecure permissions (Unix-like systems)"""
89
+ if sys.platform == 'win32':
90
+ return # Windows handles permissions differently
91
+
92
+ if os.path.exists(KEY_FILE):
93
+ try:
94
+ file_stat = os.stat(KEY_FILE)
95
+ mode = file_stat.st_mode
96
+ # Check if group or others have any permissions
97
+ if mode & (stat.S_IRWXG | stat.S_IRWXO):
98
+ print_warning(f"Key file '{KEY_FILE}' has insecure permissions!")
99
+ print_warning("Run: chmod 600 ~/.envlockr/key.key")
100
+ except OSError:
101
+ pass
102
+
103
+
104
+ # Utilities
105
+ def load_or_create_key():
106
+ """Load existing key or create a new one"""
107
+ ensure_vault_dir()
108
+
109
+ if not os.path.exists(KEY_FILE):
110
+ key = Fernet.generate_key()
111
+ # Create key file with secure permissions
112
+ flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
113
+ if sys.platform != 'win32':
114
+ fd = os.open(KEY_FILE, flags, 0o600)
115
+ with os.fdopen(fd, 'wb') as f:
116
+ f.write(key)
117
+ else:
118
+ with open(KEY_FILE, 'wb') as f:
119
+ f.write(key)
120
+ else:
121
+ try:
122
+ with open(KEY_FILE, 'rb') as f:
123
+ key = f.read()
124
+ except PermissionError:
125
+ print_error(f"Permission denied reading key file: {KEY_FILE}")
126
+ sys.exit(1)
127
+ except IOError as e:
128
+ print_error(f"Error reading key file: {e}")
129
+ sys.exit(1)
130
+
131
+ try:
132
+ return Fernet(key)
133
+ except Exception:
134
+ print_error("Invalid or corrupted key file.")
135
+ print_info("You may need to delete ~/.envlockr/key.key and start fresh.")
136
+ print_warning("WARNING: This will make existing secrets unrecoverable!")
137
+ sys.exit(1)
138
+
139
+ def load_vault():
140
+ """Load the encrypted vault from disk"""
141
+ ensure_vault_dir()
142
+
143
+ if not os.path.exists(VAULT_FILE):
144
+ return {}
145
+
146
+ try:
147
+ with open(VAULT_FILE, 'r') as f:
148
+ return json.load(f)
149
+ except json.JSONDecodeError:
150
+ print_error("Vault file is corrupted.")
151
+ print_info("You may need to delete ~/.envlockr/vault.json and start fresh.")
152
+ sys.exit(1)
153
+ except PermissionError:
154
+ print_error(f"Permission denied reading vault: {VAULT_FILE}")
155
+ sys.exit(1)
156
+ except IOError as e:
157
+ print_error(f"Error reading vault: {e}")
158
+ sys.exit(1)
159
+
160
+
161
+ def save_vault(vault):
162
+ """Save the vault to disk"""
163
+ ensure_vault_dir()
164
+
165
+ try:
166
+ with open(VAULT_FILE, 'w') as f:
167
+ json.dump(vault, f, indent=4)
168
+ except PermissionError:
169
+ print_error(f"Permission denied writing to vault: {VAULT_FILE}")
170
+ sys.exit(1)
171
+ except IOError as e:
172
+ print_error(f"Error saving vault: {e}")
173
+ sys.exit(1)
174
+
175
+
176
+ def decrypt_secret(fernet, encrypted_value):
177
+ """Safely decrypt a secret value"""
178
+ try:
179
+ return fernet.decrypt(encrypted_value.encode()).decode()
180
+ except InvalidToken:
181
+ print_error("Failed to decrypt secret. Key may have changed.")
182
+ print_info("If you regenerated your key, existing secrets cannot be recovered.")
183
+ return None
184
+ except Exception as e:
185
+ print_error(f"Decryption error: {e}")
186
+ return None
187
+
188
+
189
+ # CLI Commands
190
+ def add_secret(args):
191
+ """Add a new secret to the vault"""
192
+ fernet = load_or_create_key()
193
+ vault = load_vault()
194
+
195
+ if args.name in vault and not getattr(args, 'force', False):
196
+ print_warning(f"Secret '{args.name}' already exists.")
197
+ response = input("Overwrite? [y/N]: ").strip().lower()
198
+ if response != 'y':
199
+ print_info("Operation cancelled.")
200
+ return
201
+
202
+ secret = getpass.getpass(prompt="Enter secret value: ")
203
+ if not secret:
204
+ print_error("Secret value cannot be empty.")
205
+ return
206
+
207
+ encrypted = fernet.encrypt(secret.encode()).decode()
208
+ vault[args.name] = encrypted
209
+ save_vault(vault)
210
+ print_success(f"Secret '{args.name}' added successfully.")
211
+
212
+
213
+ def get_secret(args):
214
+ """Retrieve and display a secret"""
215
+ fernet = load_or_create_key()
216
+ vault = load_vault()
217
+
218
+ if args.name not in vault:
219
+ print_error(f"Secret '{args.name}' not found.")
220
+ print_info("Use 'envlockr list' to see available secrets.")
221
+ return
222
+
223
+ decrypted = decrypt_secret(fernet, vault[args.name])
224
+ if decrypted is not None:
225
+ print(decrypted)
226
+
227
+
228
+ def list_secrets(args):
229
+ """List all stored secret names"""
230
+ vault = load_vault()
231
+
232
+ if not vault:
233
+ print_info("No secrets stored yet.")
234
+ print_info("Add your first secret: envlockr add MY_SECRET")
235
+ return
236
+
237
+ print(f"{Colors.CYAN}🔐 Stored Secrets ({len(vault)}){Colors.NC}")
238
+ for name in sorted(vault.keys()):
239
+ print(f" {Colors.BOLD}•{Colors.NC} {name}")
240
+
241
+
242
+ def copy_secret(args):
243
+ """Copy a secret to clipboard"""
244
+ if not PYPERCLIP_AVAILABLE:
245
+ print_error("Clipboard support not available.")
246
+ print_info("Install pyperclip: pip install pyperclip")
247
+ return
248
+
249
+ fernet = load_or_create_key()
250
+ vault = load_vault()
251
+
252
+ if args.name not in vault:
253
+ print_error(f"Secret '{args.name}' not found.")
254
+ return
255
+
256
+ decrypted = decrypt_secret(fernet, vault[args.name])
257
+ if decrypted is not None:
258
+ try:
259
+ pyperclip.copy(decrypted) # type: ignore[union-attr]
260
+ print_success(f"Secret '{args.name}' copied to clipboard.")
261
+ except Exception as e:
262
+ print_error(f"Failed to copy to clipboard: {e}")
263
+ print_info("Use 'envlockr get' to display the secret instead.")
264
+
265
+
266
+ def delete_secret(args):
267
+ """Delete a secret from the vault"""
268
+ vault = load_vault()
269
+
270
+ if args.name not in vault:
271
+ print_error(f"Secret '{args.name}' not found.")
272
+ return
273
+
274
+ if not getattr(args, 'force', False):
275
+ response = input(f"Delete secret '{args.name}'? [y/N]: ").strip().lower()
276
+ if response != 'y':
277
+ print_info("Operation cancelled.")
278
+ return
279
+
280
+ del vault[args.name]
281
+ save_vault(vault)
282
+ print_success(f"Secret '{args.name}' deleted.")
283
+
284
+
285
+ def update_secret(args):
286
+ """Update an existing secret"""
287
+ fernet = load_or_create_key()
288
+ vault = load_vault()
289
+
290
+ if args.name not in vault:
291
+ print_error(f"Secret '{args.name}' not found.")
292
+ print_info("Use 'envlockr add' to create a new secret.")
293
+ return
294
+
295
+ secret = getpass.getpass(prompt="Enter new secret value: ")
296
+ if not secret:
297
+ print_error("Secret value cannot be empty.")
298
+ return
299
+
300
+ encrypted = fernet.encrypt(secret.encode()).decode()
301
+ vault[args.name] = encrypted
302
+ save_vault(vault)
303
+ print_success(f"Secret '{args.name}' updated.")
304
+
305
+
306
+ def export_secrets(args):
307
+ """Export all secrets to a .env file"""
308
+ fernet = load_or_create_key()
309
+ vault = load_vault()
310
+
311
+ if not vault:
312
+ print_info("No secrets to export.")
313
+ return
314
+
315
+ output_file = args.output if args.output else ".env"
316
+
317
+ # Check if file exists
318
+ if os.path.exists(output_file) and not getattr(args, 'force', False):
319
+ print_warning(f"File '{output_file}' already exists.")
320
+ response = input("Overwrite? [y/N]: ").strip().lower()
321
+ if response != 'y':
322
+ print_info("Operation cancelled.")
323
+ return
324
+
325
+ try:
326
+ exported_count = 0
327
+ with open(output_file, 'w') as f:
328
+ f.write(f"# Generated by EnvLockr v{__version__}\n")
329
+ f.write(f"# {len(vault)} secrets exported\n\n")
330
+ for name, encrypted_value in sorted(vault.items()):
331
+ decrypted = decrypt_secret(fernet, encrypted_value)
332
+ if decrypted is not None:
333
+ # Handle multi-line values and special characters
334
+ if '\n' in decrypted or '"' in decrypted:
335
+ f.write(f'{name}="{decrypted}"\n')
336
+ else:
337
+ f.write(f"{name}={decrypted}\n")
338
+ exported_count += 1
339
+
340
+ print_success(f"Exported {exported_count} secrets to '{output_file}'")
341
+ print_warning(f"Remember: Add '{output_file}' to .gitignore!")
342
+ except PermissionError:
343
+ print_error(f"Permission denied writing to '{output_file}'")
344
+ except IOError as e:
345
+ print_error(f"Error exporting secrets: {e}")
346
+
347
+
348
+ def import_secrets(args):
349
+ """Import secrets from a .env file"""
350
+ fernet = load_or_create_key()
351
+ vault = load_vault()
352
+
353
+ input_file = args.file
354
+
355
+ if not os.path.exists(input_file):
356
+ print_error(f"File '{input_file}' not found.")
357
+ return
358
+
359
+ try:
360
+ imported = 0
361
+ skipped = 0
362
+
363
+ with open(input_file, 'r') as f:
364
+ for line_num, line in enumerate(f, 1):
365
+ line = line.strip()
366
+
367
+ # Skip empty lines and comments
368
+ if not line or line.startswith('#'):
369
+ continue
370
+
371
+ # Parse KEY=value format
372
+ if '=' not in line:
373
+ print_warning(f"Line {line_num}: Invalid format, skipping")
374
+ skipped += 1
375
+ continue
376
+
377
+ # Split on first = only (value may contain =)
378
+ key, value = line.split('=', 1)
379
+ key = key.strip()
380
+ value = value.strip()
381
+
382
+ # Remove surrounding quotes if present
383
+ if (value.startswith('"') and value.endswith('"')) or \
384
+ (value.startswith("'") and value.endswith("'")):
385
+ value = value[1:-1]
386
+
387
+ if not key:
388
+ print_warning(f"Line {line_num}: Empty key, skipping")
389
+ skipped += 1
390
+ continue
391
+
392
+ # Check for existing secret
393
+ if key in vault and not getattr(args, 'force', False):
394
+ print_warning(f"Secret '{key}' already exists, skipping (use --force to overwrite)")
395
+ skipped += 1
396
+ continue
397
+
398
+ # Encrypt and store
399
+ encrypted = fernet.encrypt(value.encode()).decode()
400
+ vault[key] = encrypted
401
+ imported += 1
402
+
403
+ save_vault(vault)
404
+ print_success(f"Imported {imported} secrets from '{input_file}'")
405
+ if skipped > 0:
406
+ print_info(f"Skipped {skipped} entries")
407
+ print_warning(f"Consider deleting '{input_file}' now that secrets are secure!")
408
+
409
+ except PermissionError:
410
+ print_error(f"Permission denied reading '{input_file}'")
411
+ except IOError as e:
412
+ print_error(f"Error reading file: {e}")
413
+
414
+ def main():
415
+ """Main entry point for EnvLockr CLI"""
416
+ parser = argparse.ArgumentParser(
417
+ description="EnvLockr CLI - Secure Local Secrets Manager",
418
+ formatter_class=argparse.RawDescriptionHelpFormatter,
419
+ epilog="""
420
+ Examples:
421
+ envlockr add API_KEY Add a new secret
422
+ envlockr get API_KEY Retrieve a secret
423
+ envlockr copy API_KEY Copy secret to clipboard
424
+ envlockr list List all secrets
425
+ envlockr export Export to .env file
426
+ envlockr import .env Import from .env file
427
+
428
+ Documentation: https://github.com/RohanRatwani/envlockr-cli
429
+ """
430
+ )
431
+
432
+ parser.add_argument(
433
+ '--version', '-v',
434
+ action='version',
435
+ version=f'EnvLockr v{__version__}'
436
+ )
437
+
438
+ subparsers = parser.add_subparsers(dest='command', metavar='command')
439
+
440
+ # Add
441
+ add_parser = subparsers.add_parser('add', help='Add a new secret')
442
+ add_parser.add_argument('name', help='Name of the secret (e.g., API_KEY)')
443
+ add_parser.add_argument('--force', '-f', action='store_true', help='Overwrite without confirmation')
444
+ add_parser.set_defaults(func=add_secret)
445
+
446
+ # Get
447
+ get_parser = subparsers.add_parser('get', help='Retrieve a secret (prints to stdout)')
448
+ get_parser.add_argument('name', help='Name of the secret')
449
+ get_parser.set_defaults(func=get_secret)
450
+
451
+ # List
452
+ list_parser = subparsers.add_parser('list', help='List all stored secrets')
453
+ list_parser.set_defaults(func=list_secrets)
454
+
455
+ # Copy
456
+ copy_parser = subparsers.add_parser('copy', help='Copy a secret to clipboard')
457
+ copy_parser.add_argument('name', help='Name of the secret')
458
+ copy_parser.set_defaults(func=copy_secret)
459
+
460
+ # Delete
461
+ delete_parser = subparsers.add_parser('delete', help='Delete a secret')
462
+ delete_parser.add_argument('name', help='Name of the secret')
463
+ delete_parser.add_argument('--force', '-f', action='store_true', help='Delete without confirmation')
464
+ delete_parser.set_defaults(func=delete_secret)
465
+
466
+ # Update
467
+ update_parser = subparsers.add_parser('update', help='Update an existing secret')
468
+ update_parser.add_argument('name', help='Name of the secret')
469
+ update_parser.set_defaults(func=update_secret)
470
+
471
+ # Export
472
+ export_parser = subparsers.add_parser('export', help='Export secrets to .env file')
473
+ export_parser.add_argument('--output', '-o', default='.env', help='Output file path (default: .env)')
474
+ export_parser.add_argument('--force', '-f', action='store_true', help='Overwrite without confirmation')
475
+ export_parser.set_defaults(func=export_secrets)
476
+
477
+ # Import
478
+ import_parser = subparsers.add_parser('import', help='Import secrets from .env file')
479
+ import_parser.add_argument('file', help='Path to .env file to import')
480
+ import_parser.add_argument('--force', '-f', action='store_true', help='Overwrite existing secrets')
481
+ import_parser.set_defaults(func=import_secrets)
482
+
483
+ args = parser.parse_args()
484
+
485
+ # Check key file security on startup
486
+ check_key_file_security()
487
+
488
+ if hasattr(args, 'func'):
489
+ try:
490
+ args.func(args)
491
+ except KeyboardInterrupt:
492
+ print("\n")
493
+ print_info("Operation cancelled.")
494
+ sys.exit(0)
495
+ except Exception as e:
496
+ print_error(f"Unexpected error: {e}")
497
+ print_info("Please report this issue at: https://github.com/RohanRatwani/envlockr-cli/issues")
498
+ sys.exit(1)
499
+ else:
500
+ parser.print_help()
501
+
502
+
503
+ if __name__ == '__main__':
504
+ main()
@@ -0,0 +1,83 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "envlockr"
7
+ version = "1.0.0"
8
+ description = "Secure your environment variables — locally, encrypted, and stream-safe."
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ authors = [
12
+ {name = "Rohan Ratwani", email = "rohanratwani@example.com"}
13
+ ]
14
+ maintainers = [
15
+ {name = "Rohan Ratwani", email = "rohanratwani@example.com"}
16
+ ]
17
+ keywords = [
18
+ "environment-variables",
19
+ "secrets",
20
+ "encryption",
21
+ "security",
22
+ "cli",
23
+ "env",
24
+ "dotenv",
25
+ "secrets-management",
26
+ "local-first",
27
+ "developer-tools"
28
+ ]
29
+ classifiers = [
30
+ "Development Status :: 5 - Production/Stable",
31
+ "Environment :: Console",
32
+ "Intended Audience :: Developers",
33
+ "License :: OSI Approved :: MIT License",
34
+ "Operating System :: OS Independent",
35
+ "Programming Language :: Python :: 3",
36
+ "Programming Language :: Python :: 3.7",
37
+ "Programming Language :: Python :: 3.8",
38
+ "Programming Language :: Python :: 3.9",
39
+ "Programming Language :: Python :: 3.10",
40
+ "Programming Language :: Python :: 3.11",
41
+ "Programming Language :: Python :: 3.12",
42
+ "Topic :: Security",
43
+ "Topic :: Security :: Cryptography",
44
+ "Topic :: Software Development :: Libraries :: Python Modules",
45
+ "Topic :: Utilities"
46
+ ]
47
+ requires-python = ">=3.7"
48
+ dependencies = [
49
+ "cryptography>=3.4.0"
50
+ ]
51
+
52
+ [project.optional-dependencies]
53
+ clipboard = ["pyperclip>=1.8.0"]
54
+ dev = [
55
+ "pytest>=7.0.0",
56
+ "black>=22.0.0",
57
+ "flake8>=4.0.0"
58
+ ]
59
+
60
+ [project.urls]
61
+ Homepage = "https://envlockr.netlify.app"
62
+ Documentation = "https://github.com/RohanRatwani/envlockr-cli#readme"
63
+ Repository = "https://github.com/RohanRatwani/envlockr-cli"
64
+ Issues = "https://github.com/RohanRatwani/envlockr-cli/issues"
65
+ Changelog = "https://github.com/RohanRatwani/envlockr-cli/blob/main/CHANGELOG.md"
66
+
67
+ [project.scripts]
68
+ envlockr = "envlockr:main"
69
+
70
+ [tool.setuptools]
71
+ py-modules = ["envlockr"]
72
+
73
+ [tool.setuptools.packages.find]
74
+ where = ["."]
75
+ include = ["envlockr*"]
76
+
77
+ [tool.black]
78
+ line-length = 100
79
+ target-version = ['py37', 'py38', 'py39', 'py310', 'py311']
80
+
81
+ [tool.pytest.ini_options]
82
+ testpaths = ["tests"]
83
+ python_files = ["test_*.py"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+