@captainsafia/burrow 0.1.0 → 1.0.0-preview.0a24dbc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +8 -0
- package/README.md +109 -4
- package/dist/api.d.ts +251 -0
- package/dist/api.js +8 -7
- package/package.json +6 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Copyright 2025 Safia Abdalla
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
8
|
+
|
package/README.md
CHANGED
|
@@ -1,15 +1,120 @@
|
|
|
1
1
|
# burrow
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A platform-agnostic, directory-scoped secrets manager. Store secrets outside your repos, inherit them through directory ancestry.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
~/projects/ # DATABASE_URL, API_KEY defined here
|
|
7
|
+
├── app-a/ # inherits both secrets
|
|
8
|
+
├── app-b/ # inherits both, overrides API_KEY
|
|
9
|
+
│ └── tests/ # blocks API_KEY (uses none)
|
|
10
|
+
└── app-c/ # inherits both secrets
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
**Linux/macOS:**
|
|
4
16
|
|
|
5
17
|
```bash
|
|
18
|
+
curl -fsSL https://safia.rocks/burrow/install.sh | sh
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
### Set a secret
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
burrow set API_KEY=sk-live-abc123
|
|
27
|
+
burrow set DATABASE_URL=postgres://localhost/mydb --path ~/projects
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Get a secret
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
burrow get API_KEY --show
|
|
34
|
+
burrow get API_KEY --format json
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### List all secrets
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
burrow list
|
|
41
|
+
burrow list --format json
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Export to your shell
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
eval "$(burrow export)"
|
|
48
|
+
eval "$(burrow export --format shell)" && npm start
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Block inheritance
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
burrow unset API_KEY --path ~/projects/app/tests
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## How It Works
|
|
58
|
+
|
|
59
|
+
Secrets are stored in your user profile:
|
|
60
|
+
- **Linux/macOS:** `$XDG_CONFIG_HOME/burrow` or `~/.config/burrow`
|
|
61
|
+
- **Windows:** `%APPDATA%\burrow`
|
|
62
|
+
|
|
63
|
+
When you request secrets for a directory, burrow:
|
|
64
|
+
|
|
65
|
+
1. Finds all ancestor paths with stored secrets
|
|
66
|
+
2. Merges them from shallowest to deepest
|
|
67
|
+
3. Deeper scopes override shallower ones
|
|
68
|
+
4. Tombstones (from `unset`) block inheritance
|
|
69
|
+
|
|
70
|
+
## Library Usage
|
|
71
|
+
|
|
72
|
+
Burrow also works as a TypeScript/JavaScript library:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { BurrowClient } from '@captainsafia/burrow';
|
|
76
|
+
|
|
77
|
+
const client = new BurrowClient();
|
|
78
|
+
|
|
79
|
+
await client.set('API_KEY', 'secret123', { path: '/my/project' });
|
|
80
|
+
|
|
81
|
+
const secret = await client.get('API_KEY', { cwd: '/my/project/subdir' });
|
|
82
|
+
console.log(secret?.value); // 'secret123'
|
|
83
|
+
console.log(secret?.sourcePath); // '/my/project'
|
|
84
|
+
|
|
85
|
+
const allSecrets = await client.list({ cwd: '/my/project' });
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Contributing
|
|
89
|
+
|
|
90
|
+
### Prerequisites
|
|
91
|
+
|
|
92
|
+
- [Bun](https://bun.sh) v1.0 or later
|
|
93
|
+
|
|
94
|
+
### Setup
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
git clone https://github.com/captainsafia/burrow.git
|
|
98
|
+
cd burrow
|
|
6
99
|
bun install
|
|
7
100
|
```
|
|
8
101
|
|
|
9
|
-
|
|
102
|
+
### Development
|
|
10
103
|
|
|
11
104
|
```bash
|
|
12
|
-
|
|
105
|
+
# Run tests
|
|
106
|
+
bun test
|
|
107
|
+
|
|
108
|
+
# Type check
|
|
109
|
+
bun run typecheck
|
|
110
|
+
|
|
111
|
+
# Build npm package
|
|
112
|
+
bun run build
|
|
113
|
+
|
|
114
|
+
# Compile binary
|
|
115
|
+
bun run compile
|
|
13
116
|
```
|
|
14
117
|
|
|
15
|
-
|
|
118
|
+
## License
|
|
119
|
+
|
|
120
|
+
MIT
|
package/dist/api.d.ts
CHANGED
|
@@ -6,41 +6,292 @@ export interface ResolvedSecret {
|
|
|
6
6
|
sourcePath: string;
|
|
7
7
|
}
|
|
8
8
|
export type ExportFormat = "shell" | "dotenv" | "json";
|
|
9
|
+
/**
|
|
10
|
+
* Configuration options for creating a BurrowClient instance.
|
|
11
|
+
*/
|
|
9
12
|
export interface BurrowClientOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Custom directory for storing the secrets database.
|
|
15
|
+
* Defaults to platform-specific user config directory:
|
|
16
|
+
* - Linux/macOS: `$XDG_CONFIG_HOME/burrow` or `~/.config/burrow`
|
|
17
|
+
* - Windows: `%APPDATA%\burrow`
|
|
18
|
+
*
|
|
19
|
+
* Can also be set via the `BURROW_CONFIG_DIR` environment variable.
|
|
20
|
+
*/
|
|
10
21
|
configDir?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Custom filename for the secrets store.
|
|
24
|
+
* Defaults to `store.json`.
|
|
25
|
+
*/
|
|
11
26
|
storeFileName?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Whether to follow symlinks when canonicalizing paths.
|
|
29
|
+
* Defaults to `true`.
|
|
30
|
+
*/
|
|
12
31
|
followSymlinks?: boolean;
|
|
13
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Options for the `set` method.
|
|
35
|
+
*/
|
|
14
36
|
export interface SetOptions {
|
|
37
|
+
/**
|
|
38
|
+
* Directory path to scope the secret to.
|
|
39
|
+
* Defaults to the current working directory.
|
|
40
|
+
*/
|
|
15
41
|
path?: string;
|
|
16
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Options for the `get` method.
|
|
45
|
+
*/
|
|
17
46
|
export interface GetOptions {
|
|
47
|
+
/**
|
|
48
|
+
* Directory to resolve secrets from.
|
|
49
|
+
* Secrets are inherited from ancestor directories.
|
|
50
|
+
* Defaults to the current working directory.
|
|
51
|
+
*/
|
|
18
52
|
cwd?: string;
|
|
19
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Options for the `list` method.
|
|
56
|
+
*/
|
|
20
57
|
export interface ListOptions {
|
|
58
|
+
/**
|
|
59
|
+
* Directory to resolve secrets from.
|
|
60
|
+
* Secrets are inherited from ancestor directories.
|
|
61
|
+
* Defaults to the current working directory.
|
|
62
|
+
*/
|
|
21
63
|
cwd?: string;
|
|
22
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Options for the `block` method.
|
|
67
|
+
*/
|
|
23
68
|
export interface BlockOptions {
|
|
69
|
+
/**
|
|
70
|
+
* Directory path to scope the tombstone to.
|
|
71
|
+
* Defaults to the current working directory.
|
|
72
|
+
*/
|
|
24
73
|
path?: string;
|
|
25
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Options for the `export` method.
|
|
77
|
+
*/
|
|
26
78
|
export interface ExportOptions {
|
|
79
|
+
/**
|
|
80
|
+
* Directory to resolve secrets from.
|
|
81
|
+
* Secrets are inherited from ancestor directories.
|
|
82
|
+
* Defaults to the current working directory.
|
|
83
|
+
*/
|
|
27
84
|
cwd?: string;
|
|
85
|
+
/**
|
|
86
|
+
* Output format for the exported secrets.
|
|
87
|
+
* - `shell`: Exports as `export KEY='value'` statements (default)
|
|
88
|
+
* - `dotenv`: Exports as `KEY="value"` lines
|
|
89
|
+
* - `json`: Exports as a JSON object
|
|
90
|
+
*/
|
|
28
91
|
format?: ExportFormat;
|
|
92
|
+
/**
|
|
93
|
+
* Whether to show actual values (currently unused, reserved for future use).
|
|
94
|
+
*/
|
|
29
95
|
showValues?: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Whether to include source paths in JSON output.
|
|
98
|
+
* When true, JSON output includes `{ key: { value, sourcePath } }` format.
|
|
99
|
+
* Only applies when format is `json`.
|
|
100
|
+
*/
|
|
30
101
|
includeSources?: boolean;
|
|
31
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Client for managing directory-scoped secrets.
|
|
105
|
+
*
|
|
106
|
+
* Secrets are stored outside your repository in the user's config directory
|
|
107
|
+
* and are scoped to filesystem paths. Child directories automatically inherit
|
|
108
|
+
* secrets from parent directories, with deeper scopes overriding shallower ones.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* import { BurrowClient } from '@captainsafia/burrow';
|
|
113
|
+
*
|
|
114
|
+
* const client = new BurrowClient();
|
|
115
|
+
*
|
|
116
|
+
* // Set a secret scoped to a directory
|
|
117
|
+
* await client.set('API_KEY', 'sk-live-abc123', { path: '/projects/myapp' });
|
|
118
|
+
*
|
|
119
|
+
* // Get a secret (inherits from parent directories)
|
|
120
|
+
* const secret = await client.get('API_KEY', { cwd: '/projects/myapp/src' });
|
|
121
|
+
* console.log(secret?.value); // 'sk-live-abc123'
|
|
122
|
+
*
|
|
123
|
+
* // Export secrets for shell usage
|
|
124
|
+
* const shellExport = await client.export({ format: 'shell' });
|
|
125
|
+
* // Returns: export API_KEY='sk-live-abc123'
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
32
128
|
export declare class BurrowClient {
|
|
33
129
|
private readonly storage;
|
|
34
130
|
private readonly resolver;
|
|
35
131
|
private readonly pathOptions;
|
|
132
|
+
/**
|
|
133
|
+
* Creates a new BurrowClient instance.
|
|
134
|
+
*
|
|
135
|
+
* @param options - Configuration options for the client
|
|
136
|
+
*/
|
|
36
137
|
constructor(options?: BurrowClientOptions);
|
|
138
|
+
/**
|
|
139
|
+
* Sets a secret at the specified path scope.
|
|
140
|
+
*
|
|
141
|
+
* The secret will be available to the specified directory and all its
|
|
142
|
+
* subdirectories, unless overridden or blocked at a deeper level.
|
|
143
|
+
*
|
|
144
|
+
* @param key - Environment variable name. Must match `^[A-Z_][A-Z0-9_]*$`
|
|
145
|
+
* @param value - Secret value to store
|
|
146
|
+
* @param options - Set options including target path
|
|
147
|
+
* @throws Error if the key format is invalid
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* // Set at current directory
|
|
152
|
+
* await client.set('DATABASE_URL', 'postgres://localhost/mydb');
|
|
153
|
+
*
|
|
154
|
+
* // Set at specific path
|
|
155
|
+
* await client.set('API_KEY', 'secret', { path: '/projects/myapp' });
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
37
158
|
set(key: string, value: string, options?: SetOptions): Promise<void>;
|
|
159
|
+
/**
|
|
160
|
+
* Gets a secret resolved through directory ancestry.
|
|
161
|
+
*
|
|
162
|
+
* Starting from the specified directory (or cwd), walks up the directory
|
|
163
|
+
* tree to find the nearest scope that defines the key. Deeper scopes
|
|
164
|
+
* override shallower ones.
|
|
165
|
+
*
|
|
166
|
+
* @param key - Environment variable name to retrieve
|
|
167
|
+
* @param options - Get options including working directory
|
|
168
|
+
* @returns The resolved secret with its source path, or undefined if not found
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```typescript
|
|
172
|
+
* const secret = await client.get('API_KEY', { cwd: '/projects/myapp/src' });
|
|
173
|
+
* if (secret) {
|
|
174
|
+
* console.log(secret.value); // The secret value
|
|
175
|
+
* console.log(secret.sourcePath); // Path where it was defined
|
|
176
|
+
* }
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
38
179
|
get(key: string, options?: GetOptions): Promise<ResolvedSecret | undefined>;
|
|
180
|
+
/**
|
|
181
|
+
* Lists all secrets resolved for a directory.
|
|
182
|
+
*
|
|
183
|
+
* Returns all secrets that would be available in the specified directory,
|
|
184
|
+
* including those inherited from parent directories. Each secret includes
|
|
185
|
+
* its source path indicating where it was defined.
|
|
186
|
+
*
|
|
187
|
+
* @param options - List options including working directory
|
|
188
|
+
* @returns Array of resolved secrets sorted by key name
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```typescript
|
|
192
|
+
* const secrets = await client.list({ cwd: '/projects/myapp' });
|
|
193
|
+
* for (const secret of secrets) {
|
|
194
|
+
* console.log(`${secret.key} from ${secret.sourcePath}`);
|
|
195
|
+
* }
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
39
198
|
list(options?: ListOptions): Promise<ResolvedSecret[]>;
|
|
199
|
+
/**
|
|
200
|
+
* Blocks a secret from being inherited at the specified path.
|
|
201
|
+
*
|
|
202
|
+
* Creates a "tombstone" that prevents the key from being inherited from
|
|
203
|
+
* parent directories. The block only affects the specified directory and
|
|
204
|
+
* its subdirectories. The secret remains available in parent directories.
|
|
205
|
+
*
|
|
206
|
+
* A blocked key can be re-enabled by calling `set` at the same or deeper path.
|
|
207
|
+
*
|
|
208
|
+
* @param key - Environment variable name to block. Must match `^[A-Z_][A-Z0-9_]*$`
|
|
209
|
+
* @param options - Block options including target path
|
|
210
|
+
* @throws Error if the key format is invalid
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```typescript
|
|
214
|
+
* // Parent has API_KEY defined
|
|
215
|
+
* await client.set('API_KEY', 'prod-key', { path: '/projects' });
|
|
216
|
+
*
|
|
217
|
+
* // Block it in the test directory
|
|
218
|
+
* await client.block('API_KEY', { path: '/projects/myapp/tests' });
|
|
219
|
+
*
|
|
220
|
+
* // Now API_KEY won't resolve in /projects/myapp/tests or below
|
|
221
|
+
* const secret = await client.get('API_KEY', { cwd: '/projects/myapp/tests' });
|
|
222
|
+
* console.log(secret); // undefined
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
40
225
|
block(key: string, options?: BlockOptions): Promise<void>;
|
|
226
|
+
/**
|
|
227
|
+
* Exports resolved secrets in various formats.
|
|
228
|
+
*
|
|
229
|
+
* Generates a formatted string of all secrets resolved for the specified
|
|
230
|
+
* directory, suitable for shell evaluation or configuration files.
|
|
231
|
+
*
|
|
232
|
+
* @param options - Export options including format and working directory
|
|
233
|
+
* @returns Formatted string of secrets
|
|
234
|
+
*
|
|
235
|
+
* @example
|
|
236
|
+
* ```typescript
|
|
237
|
+
* // Shell format (default) - use with eval
|
|
238
|
+
* const shell = await client.export({ format: 'shell' });
|
|
239
|
+
* // Returns: export API_KEY='value'\nexport DB_URL='...'
|
|
240
|
+
*
|
|
241
|
+
* // Dotenv format - save to .env file
|
|
242
|
+
* const dotenv = await client.export({ format: 'dotenv' });
|
|
243
|
+
* // Returns: API_KEY="value"\nDB_URL="..."
|
|
244
|
+
*
|
|
245
|
+
* // JSON format - for programmatic use
|
|
246
|
+
* const json = await client.export({ format: 'json' });
|
|
247
|
+
* // Returns: { "API_KEY": "value", "DB_URL": "..." }
|
|
248
|
+
*
|
|
249
|
+
* // JSON with source paths
|
|
250
|
+
* const jsonWithSources = await client.export({
|
|
251
|
+
* format: 'json',
|
|
252
|
+
* includeSources: true
|
|
253
|
+
* });
|
|
254
|
+
* // Returns: { "API_KEY": { "value": "...", "sourcePath": "/..." } }
|
|
255
|
+
* ```
|
|
256
|
+
*/
|
|
41
257
|
export(options?: ExportOptions): Promise<string>;
|
|
258
|
+
/**
|
|
259
|
+
* Resolves all secrets for a directory as a Map.
|
|
260
|
+
*
|
|
261
|
+
* Lower-level method that returns the raw resolution result. Useful for
|
|
262
|
+
* programmatic access when you need to iterate over secrets or perform
|
|
263
|
+
* custom processing.
|
|
264
|
+
*
|
|
265
|
+
* @param cwd - Directory to resolve secrets from. Defaults to current working directory.
|
|
266
|
+
* @returns Map of key names to resolved secrets
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```typescript
|
|
270
|
+
* const secrets = await client.resolve('/projects/myapp');
|
|
271
|
+
* for (const [key, secret] of secrets) {
|
|
272
|
+
* console.log(`${key}=${secret.value} (from ${secret.sourcePath})`);
|
|
273
|
+
* }
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
42
276
|
resolve(cwd?: string): Promise<Map<string, ResolvedSecret>>;
|
|
43
277
|
}
|
|
278
|
+
/**
|
|
279
|
+
* Creates a new BurrowClient instance.
|
|
280
|
+
*
|
|
281
|
+
* Convenience function equivalent to `new BurrowClient(options)`.
|
|
282
|
+
*
|
|
283
|
+
* @param options - Configuration options for the client
|
|
284
|
+
* @returns A new BurrowClient instance
|
|
285
|
+
*
|
|
286
|
+
* @example
|
|
287
|
+
* ```typescript
|
|
288
|
+
* import { createClient } from '@captainsafia/burrow';
|
|
289
|
+
*
|
|
290
|
+
* const client = createClient({
|
|
291
|
+
* configDir: '/custom/config/path'
|
|
292
|
+
* });
|
|
293
|
+
* ```
|
|
294
|
+
*/
|
|
44
295
|
export declare function createClient(options?: BurrowClientOptions): BurrowClient;
|
|
45
296
|
|
|
46
297
|
export {};
|
package/dist/api.js
CHANGED
|
@@ -7,7 +7,12 @@ import { randomBytes } from "node:crypto";
|
|
|
7
7
|
import { homedir } from "node:os";
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
var APP_NAME = "burrow";
|
|
10
|
+
var CONFIG_DIR_ENV = "BURROW_CONFIG_DIR";
|
|
10
11
|
function getConfigDir() {
|
|
12
|
+
const envOverride = process.env[CONFIG_DIR_ENV];
|
|
13
|
+
if (envOverride) {
|
|
14
|
+
return envOverride;
|
|
15
|
+
}
|
|
11
16
|
const platform = process.platform;
|
|
12
17
|
if (platform === "win32") {
|
|
13
18
|
return getWindowsConfigDir();
|
|
@@ -170,11 +175,8 @@ function isAncestorOf(ancestorPath, descendantPath) {
|
|
|
170
175
|
class Resolver {
|
|
171
176
|
storage;
|
|
172
177
|
pathOptions;
|
|
173
|
-
constructor(options
|
|
174
|
-
this.storage =
|
|
175
|
-
configDir: options.configDir,
|
|
176
|
-
storeFileName: options.storeFileName
|
|
177
|
-
});
|
|
178
|
+
constructor(options) {
|
|
179
|
+
this.storage = options.storage;
|
|
178
180
|
this.pathOptions = {
|
|
179
181
|
followSymlinks: options.followSymlinks
|
|
180
182
|
};
|
|
@@ -306,8 +308,7 @@ class BurrowClient {
|
|
|
306
308
|
storeFileName: options.storeFileName
|
|
307
309
|
});
|
|
308
310
|
this.resolver = new Resolver({
|
|
309
|
-
|
|
310
|
-
storeFileName: options.storeFileName,
|
|
311
|
+
storage: this.storage,
|
|
311
312
|
followSymlinks: options.followSymlinks
|
|
312
313
|
});
|
|
313
314
|
this.pathOptions = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@captainsafia/burrow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-preview.0a24dbc",
|
|
4
4
|
"description": "Platform-agnostic, directory-scoped secrets manager",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/api.js",
|
|
@@ -49,5 +49,8 @@
|
|
|
49
49
|
"direnv",
|
|
50
50
|
"configuration"
|
|
51
51
|
],
|
|
52
|
-
"license": "MIT"
|
|
53
|
-
|
|
52
|
+
"license": "MIT",
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"commander": "^14.0.2"
|
|
55
|
+
}
|
|
56
|
+
}
|