slickenv 0.0.3 → 1.0.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.
package/README.md CHANGED
@@ -1,60 +1,65 @@
1
1
  # SlickEnv
2
2
 
3
- CLI tool for securely managing, syncing, and versioning `.env` files across your team.
3
+ **By [SlickSpender](https://slickspender.com)**
4
+
5
+ Securely manage, sync, and version `.env` files across your team with end-to-end encryption.
4
6
 
5
7
  - **End-to-end encrypted** — Private variables are encrypted client-side with AES-256-GCM before leaving your machine
6
8
  - **Version history** — Every push creates an immutable version you can diff, rollback, or audit
7
9
  - **Team sync** — Pull the latest environment from anywhere, always in sync
10
+ - **Team management** — Invite members with role-based access (admin, member, viewer)
8
11
  - **Zero plaintext on server** — The server never sees your unencrypted secrets
9
12
 
10
13
  ## Install
11
14
 
12
15
  ```bash
13
16
  npm install -g slickenv
17
+ # or
18
+ npx slickenv
14
19
  ```
15
20
 
16
21
  ## Quick Start
17
22
 
18
23
  ```bash
19
- # Authenticate via browser
24
+ # 1. Authenticate via browser
20
25
  slickenv login
21
26
 
22
- # Initialize a project in your repo
27
+ # 2. Initialize a project in your repo
23
28
  slickenv init --name my-app
24
29
 
25
- # Push your .env to SlickEnv
30
+ # 3. Push your .env to SlickEnv
26
31
  slickenv push -m "Initial environment"
27
32
 
28
- # Pull from another machine or teammate
33
+ # 4. Pull from another machine or teammate
29
34
  slickenv pull
35
+
36
+ # 5. Invite a teammate
37
+ slickenv members invite teammate@company.com --role member
30
38
  ```
31
39
 
32
40
  ## Commands
33
41
 
34
42
  ### Authentication
35
43
 
36
- #### `slickenv login`
37
-
38
- Open browser to authenticate via OAuth. Your token is stored securely in the OS keychain (with a file fallback).
39
-
40
- #### `slickenv logout`
41
-
42
- Revoke your token and clear local credentials.
44
+ | Command | Description |
45
+ | ------------------ | ------------------------------------------------ |
46
+ | `slickenv login` | Authenticate via browser OAuth (stored in OS keychain) |
47
+ | `slickenv logout` | Revoke your token and clear local credentials |
43
48
 
44
49
  ### Project Setup
45
50
 
46
- #### `slickenv init`
47
-
48
- Initialize a SlickEnv project in the current directory. Creates a `.slickenv` config file and ensures `.env` is in your `.gitignore`.
51
+ | Command | Description |
52
+ | ---------------- | -------------------------------------------------- |
53
+ | `slickenv init` | Initialize a SlickEnv project in the current directory |
49
54
 
50
55
  ```bash
51
56
  slickenv init --name my-app --env production
52
57
  ```
53
58
 
54
- | Flag | Description | Default |
55
- | ------- | ------------------------------------ | -------------------- |
56
- | `--name`| Project name | Current directory |
57
- | `--env` | Default environment label | `production` |
59
+ | Flag | Description | Default |
60
+ | ------- | -------------------------- | ----------------- |
61
+ | `--name`| Project name | Current directory |
62
+ | `--env` | Default environment label | `production` |
58
63
 
59
64
  ### Syncing
60
65
 
@@ -66,12 +71,12 @@ Push local `.env` changes to SlickEnv. Private variables are encrypted before up
66
71
  slickenv push -m "Add Stripe keys" --yes
67
72
  ```
68
73
 
69
- | Flag | Description | Default |
70
- | --------------- | ------------------------------------ | -------- |
71
- | `--file` | Path to env file | `.env` |
72
- | `--force` | Skip conflict check | `false` |
73
- | `--message, -m` | Version description | — |
74
- | `--yes, -y` | Auto-confirm prompts | `false` |
74
+ | Flag | Description | Default |
75
+ | --------------- | -------------------------- | -------- |
76
+ | `--file` | Path to env file | `.env` |
77
+ | `--force` | Skip conflict check | `false` |
78
+ | `--message, -m` | Version description | — |
79
+ | `--yes, -y` | Auto-confirm prompts | `false` |
75
80
 
76
81
  #### `slickenv pull`
77
82
 
@@ -81,11 +86,15 @@ Pull the latest (or a specific) version and write it to your local `.env`.
81
86
  slickenv pull --version 3 --dry-run
82
87
  ```
83
88
 
84
- | Flag | Description | Default |
85
- | ----------- | ---------------------------------- | -------- |
86
- | `--version` | Pull a specific version | latest |
87
- | `--dry-run` | Preview without writing to disk | `false` |
88
- | `--yes, -y` | Auto-confirm overwrite | `false` |
89
+ | Flag | Description | Default |
90
+ | ----------- | -------------------------------- | -------- |
91
+ | `--version` | Pull a specific version | latest |
92
+ | `--dry-run` | Preview without writing to disk | `false` |
93
+ | `--yes, -y` | Auto-confirm overwrite | `false` |
94
+
95
+ #### `slickenv status`
96
+
97
+ Show what's different between your local `.env` and the remote version.
89
98
 
90
99
  ### Version History
91
100
 
@@ -97,9 +106,9 @@ List version history for the current environment.
97
106
  slickenv versions --limit 10
98
107
  ```
99
108
 
100
- | Flag | Description | Default |
101
- | --------- | ------------------------- | ------- |
102
- | `--limit` | Number of versions | `20` |
109
+ | Flag | Description | Default |
110
+ | --------- | ------------------- | ------- |
111
+ | `--limit` | Number of versions | `20` |
103
112
 
104
113
  #### `slickenv diff <version-a> <version-b>`
105
114
 
@@ -123,6 +132,21 @@ slickenv rollback 2 --yes
123
132
 
124
133
  ### Sharing
125
134
 
135
+ #### `slickenv share`
136
+
137
+ Generate a shareable view of the current environment. Private values are masked by default.
138
+
139
+ ```bash
140
+ slickenv share
141
+ slickenv share --public-only
142
+ slickenv share --reveal
143
+ ```
144
+
145
+ | Flag | Description | Default |
146
+ | --------------- | ------------------------------ | ------- |
147
+ | `--public-only` | Show only public variables | `false` |
148
+ | `--reveal` | Show private values in plain | `false` |
149
+
126
150
  #### `slickenv export`
127
151
 
128
152
  Generate a `.env.example` file with metadata annotations. Public variables include their values; private variables show only examples or placeholders.
@@ -131,37 +155,57 @@ Generate a `.env.example` file with metadata annotations. Public variables inclu
131
155
  slickenv export --out .env.example
132
156
  ```
133
157
 
134
- | Flag | Description | Default |
135
- | ------- | ------------------ | --------------- |
136
- | `--out` | Output file path | `.env.example` |
158
+ | Flag | Description | Default |
159
+ | ------- | ----------------- | -------------- |
160
+ | `--out` | Output file path | `.env.example` |
137
161
 
138
- #### `slickenv share`
162
+ ### Team Management
139
163
 
140
- Display a shareable view of the current environment. Private values are masked by default.
164
+ #### `slickenv members list`
165
+
166
+ List all members of the current project, including their roles.
141
167
 
142
168
  ```bash
143
- slickenv share --public-only
144
- slickenv share --reveal
169
+ slickenv members list
170
+ slickenv members list --json
145
171
  ```
146
172
 
147
- | Flag | Description | Default |
148
- | --------------- | ------------------------------- | ------- |
149
- | `--public-only` | Show only public variables | `false` |
150
- | `--reveal` | Show private values in plain | `false` |
173
+ #### `slickenv members invite <email>`
151
174
 
152
- #### `slickenv status`
175
+ Invite a user to the current project. The user must already have a SlickEnv account.
153
176
 
154
- Show what's different between your local `.env` and the remote version.
177
+ ```bash
178
+ slickenv members invite user@example.com
179
+ slickenv members invite user@example.com --role admin
180
+ slickenv members invite user@example.com --role viewer
181
+ ```
182
+
183
+ | Flag | Description | Options | Default |
184
+ | -------- | --------------- | --------------------------- | -------- |
185
+ | `--role` | Role to assign | `admin`, `member`, `viewer` | `member` |
186
+
187
+ **Roles:**
188
+ - **admin** — Full access including member management
189
+ - **member** — Read and write access to environments
190
+ - **viewer** — Read-only access
191
+
192
+ #### `slickenv members remove <email>`
193
+
194
+ Remove a member from the current project (with confirmation).
195
+
196
+ ```bash
197
+ slickenv members remove user@example.com
198
+ ```
155
199
 
156
200
  ### Global Flags
157
201
 
158
202
  All commands support:
159
203
 
160
- | Flag | Description |
161
- | ------------ | ------------------------ |
162
- | `--json` | Output as JSON |
163
- | `--no-color` | Disable colored output |
164
- | `--verbose` | Show debug information |
204
+ | Flag | Description |
205
+ | ------------ | ----------------------- |
206
+ | `--json` | Output as JSON |
207
+ | `--no-color` | Disable colored output |
208
+ | `--verbose` | Show debug information |
165
209
 
166
210
  ## `.env` Metadata Annotations
167
211
 
@@ -175,12 +219,12 @@ APP_NAME=my-app
175
219
  STRIPE_SECRET_KEY=sk_live_abc123
176
220
  ```
177
221
 
178
- | Annotation | Values | Default |
179
- | --------------- | ------------------------------ | ----------- |
180
- | `@visibility` | `public`, `private` | `private` |
181
- | `@type` | `string`, `number`, `boolean` | `string` |
182
- | `@required` | `true`, `false` | `false` |
183
- | `@example` | Any value | — |
222
+ | Annotation | Values | Default |
223
+ | ------------- | ----------------------------- | --------- |
224
+ | `@visibility` | `public`, `private` | `private` |
225
+ | `@type` | `string`, `number`, `boolean` | `string` |
226
+ | `@required` | `true`, `false` | `false` |
227
+ | `@example` | Any value | — |
184
228
 
185
229
  Variables marked `private` are encrypted client-side before syncing. Variables marked `public` are stored in plaintext.
186
230
 
@@ -193,18 +237,26 @@ SlickEnv uses **client-side AES-256-GCM encryption** so private variables never
193
237
  - **Token storage**: OS keychain via keytar, with a chmod 600 file fallback
194
238
  - **Zero knowledge**: The server stores only ciphertext — it cannot read your private variables
195
239
 
240
+ ## CI/CD
241
+
242
+ Set the `SLICKENV_TOKEN` environment variable to authenticate non-interactively:
243
+
244
+ ```bash
245
+ SLICKENV_TOKEN=your-token slickenv pull --yes
246
+ ```
247
+
196
248
  ## Environment Variables
197
249
 
198
- | Variable | Description | Default |
199
- | ------------------- | ------------------------------------ | ------------------------------------- |
200
- | `SLICKENV_API_URL` | Override the backend API URL | `https://apienv.slickspender.com` |
201
- | `SLICKENV_AUTH_URL` | Override the auth website URL | `https://env.slickspender.com` |
202
- | `SLICKENV_TOKEN` | Use a token directly (CI/CD) | — |
250
+ | Variable | Description | Default |
251
+ | ------------------- | ---------------------------- | --------------------------------- |
252
+ | `SLICKENV_API_URL` | Override the backend API URL | `https://apienv.slickspender.com` |
253
+ | `SLICKENV_AUTH_URL` | Override the auth website URL| `https://env.slickspender.com` |
254
+ | `SLICKENV_TOKEN` | Use a token directly (CI/CD)| — |
203
255
 
204
256
  ## Documentation
205
257
 
206
- Full documentation is available at [env.slickspender.com/docs](https://env.slickspender.com/docs).
258
+ Full documentation at [env.slickspender.com/docs](https://env.slickspender.com/docs).
207
259
 
208
260
  ## License
209
261
 
210
- MIT
262
+ MIT — [SlickSpender](https://slickspender.com)
@@ -0,0 +1,16 @@
1
+ import { BaseCommand } from "../../base-command.js";
2
+ export default class MembersInvite extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ email: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ role: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ "no-color": import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
+ };
14
+ run(): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=invite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invite.d.ts","sourceRoot":"","sources":["../../../src/commands/members/invite.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW;IACpD,OAAgB,WAAW,SAA4C;IAEvE,OAAgB,QAAQ,WAItB;IAEF,OAAgB,IAAI;;MAKlB;IAEF,OAAgB,KAAK;;;;;MAOnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAiB3B"}
@@ -0,0 +1,42 @@
1
+ import { Args, Flags } from "@oclif/core";
2
+ import { BaseCommand } from "../../base-command.js";
3
+ import { createApiClient } from "../../lib/api.js";
4
+ export default class MembersInvite extends BaseCommand {
5
+ static description = "Invite a member to the current project";
6
+ static examples = [
7
+ "slickenv members invite user@example.com",
8
+ "slickenv members invite user@example.com --role admin",
9
+ "slickenv members invite user@example.com --role viewer",
10
+ ];
11
+ static args = {
12
+ email: Args.string({
13
+ description: "Email address of the user to invite",
14
+ required: true,
15
+ }),
16
+ };
17
+ static flags = {
18
+ ...BaseCommand.baseFlags,
19
+ role: Flags.string({
20
+ description: "Role to assign",
21
+ options: ["admin", "member", "viewer"],
22
+ default: "member",
23
+ }),
24
+ };
25
+ async run() {
26
+ const { args, flags } = await this.parse(MembersInvite);
27
+ const client = createApiClient(this.slickenvConfig.apiUrl, this.authToken);
28
+ try {
29
+ await client.mutation("members:invite", {
30
+ projectId: this.slickenvConfig.projectId,
31
+ email: args.email,
32
+ role: flags.role,
33
+ });
34
+ }
35
+ catch (error) {
36
+ const msg = error?.data?.message ?? error?.message ?? "Failed to invite member.";
37
+ this.fail(msg);
38
+ }
39
+ this.success(`Invited ${args.email} as ${flags.role}.`);
40
+ }
41
+ }
42
+ //# sourceMappingURL=invite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invite.js","sourceRoot":"","sources":["../../../src/commands/members/invite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW;IACpD,MAAM,CAAU,WAAW,GAAG,wCAAwC,CAAC;IAEvE,MAAM,CAAU,QAAQ,GAAG;QACzB,0CAA0C;QAC1C,uDAAuD;QACvD,wDAAwD;KACzD,CAAC;IAEF,MAAM,CAAU,IAAI,GAAG;QACrB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC;YACjB,WAAW,EAAE,qCAAqC;YAClD,QAAQ,EAAE,IAAI;SACf,CAAC;KACH,CAAC;IAEF,MAAM,CAAU,KAAK,GAAG;QACtB,GAAG,WAAW,CAAC,SAAS;QACxB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;YACjB,WAAW,EAAE,gBAAgB;YAC7B,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC;YACtC,OAAO,EAAE,QAAQ;SAClB,CAAC;KACH,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAE3E,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,QAAQ,CAAC,gBAAuB,EAAE;gBAC7C,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,SAAS;gBACxC,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,IAAI,EAAE,KAAK,CAAC,IAAqC;aAClD,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,GAAG,GAAG,KAAK,EAAE,IAAI,EAAE,OAAO,IAAI,KAAK,EAAE,OAAO,IAAI,0BAA0B,CAAC;YACjF,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,KAAK,OAAO,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;IAC1D,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { BaseCommand } from "../../base-command.js";
2
+ export default class MembersList extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ "no-color": import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ };
10
+ run(): Promise<void>;
11
+ }
12
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/members/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,WAAW;IAClD,OAAgB,WAAW,SAA6C;IAExE,OAAgB,QAAQ,WAGtB;IAEF,OAAgB,KAAK;;;;MAEnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA6B3B"}
@@ -0,0 +1,38 @@
1
+ import { BaseCommand } from "../../base-command.js";
2
+ import { createApiClient } from "../../lib/api.js";
3
+ import { colors } from "../../lib/output.js";
4
+ export default class MembersList extends BaseCommand {
5
+ static description = "List all members of the current project";
6
+ static examples = [
7
+ "slickenv members list",
8
+ "slickenv members list --json",
9
+ ];
10
+ static flags = {
11
+ ...BaseCommand.baseFlags,
12
+ };
13
+ async run() {
14
+ const { flags } = await this.parse(MembersList);
15
+ const client = createApiClient(this.slickenvConfig.apiUrl, this.authToken);
16
+ const members = (await client.query("members:listMembers", {
17
+ projectId: this.slickenvConfig.projectId,
18
+ }));
19
+ if (flags.json) {
20
+ this.log(JSON.stringify(members, null, 2));
21
+ return;
22
+ }
23
+ this.log("");
24
+ this.log(` ${colors.key(this.slickenvConfig.projectName)} — ${members.length} member${members.length === 1 ? "" : "s"}`);
25
+ this.log("");
26
+ for (const m of members) {
27
+ const role = m.role === "owner"
28
+ ? colors.warning("owner")
29
+ : m.role === "admin"
30
+ ? colors.success("admin")
31
+ : colors.info(m.role);
32
+ const name = m.name ? `${m.name} ` : "";
33
+ this.log(` ${name}${colors.email(m.email)} ${role}`);
34
+ }
35
+ this.log("");
36
+ }
37
+ }
38
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/members/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,WAAW;IAClD,MAAM,CAAU,WAAW,GAAG,yCAAyC,CAAC;IAExE,MAAM,CAAU,QAAQ,GAAG;QACzB,uBAAuB;QACvB,8BAA8B;KAC/B,CAAC;IAEF,MAAM,CAAU,KAAK,GAAG;QACtB,GAAG,WAAW,CAAC,SAAS;KACzB,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAE3E,MAAM,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,qBAA4B,EAAE;YAChE,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,SAAS;SACzC,CAAC,CAAU,CAAC;QAEb,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC3C,OAAO;QACT,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,MAAM,OAAO,CAAC,MAAM,UAAU,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QAC1H,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEb,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,KAAK,OAAO;gBAC7B,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;gBACzB,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO;oBAClB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;oBACzB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC1B,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QACzD,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { BaseCommand } from "../../base-command.js";
2
+ export default class MembersRemove extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ email: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ "no-color": import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ };
13
+ run(): Promise<void>;
14
+ }
15
+ //# sourceMappingURL=remove.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../../../src/commands/members/remove.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW;IACpD,OAAgB,WAAW,SAA8C;IAEzE,OAAgB,QAAQ,WAEtB;IAEF,OAAgB,IAAI;;MAKlB;IAEF,OAAgB,KAAK;;;;MAEnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAuC3B"}
@@ -0,0 +1,51 @@
1
+ import { Args } from "@oclif/core";
2
+ import { BaseCommand } from "../../base-command.js";
3
+ import { createApiClient } from "../../lib/api.js";
4
+ import { confirm } from "../../lib/output.js";
5
+ export default class MembersRemove extends BaseCommand {
6
+ static description = "Remove a member from the current project";
7
+ static examples = [
8
+ "slickenv members remove user@example.com",
9
+ ];
10
+ static args = {
11
+ email: Args.string({
12
+ description: "Email address of the member to remove",
13
+ required: true,
14
+ }),
15
+ };
16
+ static flags = {
17
+ ...BaseCommand.baseFlags,
18
+ };
19
+ async run() {
20
+ const { args } = await this.parse(MembersRemove);
21
+ const client = createApiClient(this.slickenvConfig.apiUrl, this.authToken);
22
+ // First, list members to find the userId for the given email
23
+ const members = (await client.query("members:listMembers", {
24
+ projectId: this.slickenvConfig.projectId,
25
+ }));
26
+ const target = members.find((m) => m.email.toLowerCase() === args.email.toLowerCase());
27
+ if (!target) {
28
+ this.fail(`No member found with email "${args.email}".`);
29
+ }
30
+ if (target.role === "owner") {
31
+ this.fail("The project owner cannot be removed.");
32
+ }
33
+ const ok = await confirm(`Remove ${args.email} from this project?`);
34
+ if (!ok) {
35
+ this.info("Cancelled.");
36
+ return;
37
+ }
38
+ try {
39
+ await client.mutation("members:remove", {
40
+ projectId: this.slickenvConfig.projectId,
41
+ userId: target.userId,
42
+ });
43
+ }
44
+ catch (error) {
45
+ const msg = error?.data?.message ?? error?.message ?? "Failed to remove member.";
46
+ this.fail(msg);
47
+ }
48
+ this.success(`Removed ${args.email} from the project.`);
49
+ }
50
+ }
51
+ //# sourceMappingURL=remove.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove.js","sourceRoot":"","sources":["../../../src/commands/members/remove.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW;IACpD,MAAM,CAAU,WAAW,GAAG,0CAA0C,CAAC;IAEzE,MAAM,CAAU,QAAQ,GAAG;QACzB,0CAA0C;KAC3C,CAAC;IAEF,MAAM,CAAU,IAAI,GAAG;QACrB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC;YACjB,WAAW,EAAE,uCAAuC;YACpD,QAAQ,EAAE,IAAI;SACf,CAAC;KACH,CAAC;IAEF,MAAM,CAAU,KAAK,GAAG;QACtB,GAAG,WAAW,CAAC,SAAS;KACzB,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAE3E,6DAA6D;QAC7D,MAAM,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,qBAA4B,EAAE;YAChE,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,SAAS;SACzC,CAAC,CAAU,CAAC;QAEb,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CACzB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAC1D,CAAC;QAEF,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC,IAAI,CAAC,+BAA+B,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;QAC3D,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,UAAU,IAAI,CAAC,KAAK,qBAAqB,CAAC,CAAC;QACpE,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACxB,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,QAAQ,CAAC,gBAAuB,EAAE;gBAC7C,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,SAAS;gBACxC,MAAM,EAAE,MAAM,CAAC,MAAM;aACtB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,GAAG,GAAG,KAAK,EAAE,IAAI,EAAE,OAAO,IAAI,KAAK,EAAE,OAAO,IAAI,0BAA0B,CAAC;YACjF,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,KAAK,oBAAoB,CAAC,CAAC;IAC1D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AASjD,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,WAAW;IAC3C,OAAgB,WAAW,SAAyC;IAEpE,OAAgB,QAAQ,WAKtB;IAEF,OAAgB,KAAK;;;;;;;;MAmBnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YA+GZ,iBAAiB;CAWhC"}
1
+ {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AASjD,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,WAAW;IAC3C,OAAgB,WAAW,SAAyC;IAEpE,OAAgB,QAAQ,WAKtB;IAEF,OAAgB,KAAK;;;;;;;;MAmBnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAgJZ,iBAAiB;CAWhC"}
@@ -3,7 +3,7 @@ import { join } from "node:path";
3
3
  import { Flags } from "@oclif/core";
4
4
  import { BaseCommand } from "../base-command.js";
5
5
  import { parseEnvFile, serializeEnvFile } from "../lib/parser.js";
6
- import { deriveKey, encrypt } from "../lib/crypto.js";
6
+ import { deriveKey, encrypt, decrypt } from "../lib/crypto.js";
7
7
  import { createApiClient } from "../lib/api.js";
8
8
  import { decodeJwt } from "../lib/auth.js";
9
9
  import { writeConfig, findConfigDir, loadConfig } from "../lib/config.js";
@@ -76,6 +76,35 @@ export default class Push extends BaseCommand {
76
76
  const clerkUserId = jwt.sub;
77
77
  const salt = Buffer.from(project.salt, "base64");
78
78
  const key = deriveKey(clerkUserId, this.slickenvConfig.projectId, salt);
79
+ // Check if there are actual changes compared to remote
80
+ try {
81
+ const remote = await client.query("environments:pull", {
82
+ projectId: this.slickenvConfig.projectId,
83
+ label: this.slickenvConfig.defaultEnvironment,
84
+ });
85
+ if (remote?.variables) {
86
+ const remoteMap = new Map();
87
+ for (const rv of remote.variables) {
88
+ let value = rv.value;
89
+ if (rv.isEncrypted && rv.iv) {
90
+ value = decrypt(rv.value, rv.iv, key);
91
+ }
92
+ remoteMap.set(rv.key, { value, visibility: rv.visibility, type: rv.type, required: rv.required });
93
+ }
94
+ const hasChanges = parsed.length !== remoteMap.size ||
95
+ parsed.some((v) => {
96
+ const r = remoteMap.get(v.key);
97
+ return !r || r.value !== v.value || r.visibility !== v.visibility || r.type !== v.type || r.required !== v.required;
98
+ });
99
+ if (!hasChanges) {
100
+ this.info("No changes detected. Local .env matches the remote version.");
101
+ return;
102
+ }
103
+ }
104
+ }
105
+ catch {
106
+ // No remote version yet — this is the first push, continue
107
+ }
79
108
  // Encrypt private variables
80
109
  const variables = parsed.map((v) => {
81
110
  if (v.visibility === "private") {
@@ -1 +1 @@
1
- {"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"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"}
@@ -17,8 +17,12 @@ export declare function isNearExpiry(token: string): boolean;
17
17
  */
18
18
  export declare function resolveToken(): Promise<string | null>;
19
19
  /**
20
- * Get a valid auth token, refreshing if near expiry.
20
+ * Get a valid auth token.
21
21
  * Throws AuthError if no token or token is expired.
22
+ *
23
+ * Note: Token lifetime is controlled by the Clerk JWT template settings.
24
+ * Set "Token Lifetime" on the "convex" template in the Clerk Dashboard
25
+ * (recommended: 2592000 = 30 days for CLI usage).
22
26
  */
23
27
  export declare function getValidToken(): Promise<string>;
24
28
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYhE;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAIhD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAKnD;AAED;;;GAGG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQ3D;AAmBD;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CA6BrD"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYhE;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAIhD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAKnD;AAED;;;GAGG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQ3D;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAkBrD"}
package/dist/lib/auth.js CHANGED
@@ -1,6 +1,5 @@
1
- import { getStoredToken, storeToken } from "./keychain.js";
1
+ import { getStoredToken } from "./keychain.js";
2
2
  import { AuthError } from "./errors.js";
3
- const CLERK_API_URL = "https://api.clerk.dev";
4
3
  /**
5
4
  * Decode a JWT payload without verifying the signature.
6
5
  * Signature verification is done server-side by Convex.
@@ -50,22 +49,12 @@ export async function resolveToken() {
50
49
  return getStoredToken();
51
50
  }
52
51
  /**
53
- * Attempt to refresh an expiring token via Clerk.
54
- */
55
- async function refreshToken(token) {
56
- const response = await fetch(`${CLERK_API_URL}/tokens/refresh`, {
57
- method: "POST",
58
- headers: { Authorization: `Bearer ${token}` },
59
- });
60
- if (!response.ok) {
61
- throw new Error("Refresh failed");
62
- }
63
- const data = (await response.json());
64
- return data.jwt;
65
- }
66
- /**
67
- * Get a valid auth token, refreshing if near expiry.
52
+ * Get a valid auth token.
68
53
  * Throws AuthError if no token or token is expired.
54
+ *
55
+ * Note: Token lifetime is controlled by the Clerk JWT template settings.
56
+ * Set "Token Lifetime" on the "convex" template in the Clerk Dashboard
57
+ * (recommended: 2592000 = 30 days for CLI usage).
69
58
  */
70
59
  export async function getValidToken() {
71
60
  const token = await resolveToken();
@@ -75,17 +64,6 @@ export async function getValidToken() {
75
64
  if (isExpired(token)) {
76
65
  throw new AuthError("TOKEN_EXPIRED", "Session expired. Run `slickenv login` to reconnect.");
77
66
  }
78
- if (isNearExpiry(token)) {
79
- try {
80
- const refreshed = await refreshToken(token);
81
- await storeToken(refreshed);
82
- return refreshed;
83
- }
84
- catch {
85
- // Refresh failed but token still valid — proceed
86
- return token;
87
- }
88
- }
89
67
  return token;
90
68
  }
91
69
  //# sourceMappingURL=auth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,SAAS,CAAC,eAAe,EAAE,wDAAwD,CAAC,CAAC;IACjG,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAA4B,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,SAAS,CAAC,eAAe,EAAE,wDAAwD,CAAC,CAAC;IACjG,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,MAAM,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACzC,OAAO,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,MAAM,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,kBAAkB,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC;IAC/D,OAAO,GAAG,GAAG,kBAAkB,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,kCAAkC;IAClC,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;QAC/B,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IACpC,CAAC;IAED,iCAAiC;IACjC,OAAO,cAAc,EAAE,CAAC;AAC1B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;IAEnC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,SAAS,CACjB,mBAAmB,EACnB,0CAA0C,CAC3C,CAAC;IACJ,CAAC;IAED,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,SAAS,CACjB,eAAe,EACf,qDAAqD,CACtD,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -588,7 +588,164 @@
588
588
  "commands",
589
589
  "versions.js"
590
590
  ]
591
+ },
592
+ "members:invite": {
593
+ "aliases": [],
594
+ "args": {
595
+ "email": {
596
+ "description": "Email address of the user to invite",
597
+ "name": "email",
598
+ "required": true
599
+ }
600
+ },
601
+ "description": "Invite a member to the current project",
602
+ "examples": [
603
+ "slickenv members invite user@example.com",
604
+ "slickenv members invite user@example.com --role admin",
605
+ "slickenv members invite user@example.com --role viewer"
606
+ ],
607
+ "flags": {
608
+ "json": {
609
+ "description": "Output as JSON",
610
+ "name": "json",
611
+ "allowNo": false,
612
+ "type": "boolean"
613
+ },
614
+ "no-color": {
615
+ "description": "Disable colour output",
616
+ "name": "no-color",
617
+ "allowNo": false,
618
+ "type": "boolean"
619
+ },
620
+ "verbose": {
621
+ "description": "Show additional debug information",
622
+ "name": "verbose",
623
+ "allowNo": false,
624
+ "type": "boolean"
625
+ },
626
+ "role": {
627
+ "description": "Role to assign",
628
+ "name": "role",
629
+ "default": "member",
630
+ "hasDynamicHelp": false,
631
+ "multiple": false,
632
+ "options": [
633
+ "admin",
634
+ "member",
635
+ "viewer"
636
+ ],
637
+ "type": "option"
638
+ }
639
+ },
640
+ "hasDynamicHelp": false,
641
+ "hiddenAliases": [],
642
+ "id": "members:invite",
643
+ "pluginAlias": "slickenv",
644
+ "pluginName": "slickenv",
645
+ "pluginType": "core",
646
+ "strict": true,
647
+ "enableJsonFlag": false,
648
+ "isESM": true,
649
+ "relativePath": [
650
+ "dist",
651
+ "commands",
652
+ "members",
653
+ "invite.js"
654
+ ]
655
+ },
656
+ "members:list": {
657
+ "aliases": [],
658
+ "args": {},
659
+ "description": "List all members of the current project",
660
+ "examples": [
661
+ "slickenv members list",
662
+ "slickenv members list --json"
663
+ ],
664
+ "flags": {
665
+ "json": {
666
+ "description": "Output as JSON",
667
+ "name": "json",
668
+ "allowNo": false,
669
+ "type": "boolean"
670
+ },
671
+ "no-color": {
672
+ "description": "Disable colour output",
673
+ "name": "no-color",
674
+ "allowNo": false,
675
+ "type": "boolean"
676
+ },
677
+ "verbose": {
678
+ "description": "Show additional debug information",
679
+ "name": "verbose",
680
+ "allowNo": false,
681
+ "type": "boolean"
682
+ }
683
+ },
684
+ "hasDynamicHelp": false,
685
+ "hiddenAliases": [],
686
+ "id": "members:list",
687
+ "pluginAlias": "slickenv",
688
+ "pluginName": "slickenv",
689
+ "pluginType": "core",
690
+ "strict": true,
691
+ "enableJsonFlag": false,
692
+ "isESM": true,
693
+ "relativePath": [
694
+ "dist",
695
+ "commands",
696
+ "members",
697
+ "list.js"
698
+ ]
699
+ },
700
+ "members:remove": {
701
+ "aliases": [],
702
+ "args": {
703
+ "email": {
704
+ "description": "Email address of the member to remove",
705
+ "name": "email",
706
+ "required": true
707
+ }
708
+ },
709
+ "description": "Remove a member from the current project",
710
+ "examples": [
711
+ "slickenv members remove user@example.com"
712
+ ],
713
+ "flags": {
714
+ "json": {
715
+ "description": "Output as JSON",
716
+ "name": "json",
717
+ "allowNo": false,
718
+ "type": "boolean"
719
+ },
720
+ "no-color": {
721
+ "description": "Disable colour output",
722
+ "name": "no-color",
723
+ "allowNo": false,
724
+ "type": "boolean"
725
+ },
726
+ "verbose": {
727
+ "description": "Show additional debug information",
728
+ "name": "verbose",
729
+ "allowNo": false,
730
+ "type": "boolean"
731
+ }
732
+ },
733
+ "hasDynamicHelp": false,
734
+ "hiddenAliases": [],
735
+ "id": "members:remove",
736
+ "pluginAlias": "slickenv",
737
+ "pluginName": "slickenv",
738
+ "pluginType": "core",
739
+ "strict": true,
740
+ "enableJsonFlag": false,
741
+ "isESM": true,
742
+ "relativePath": [
743
+ "dist",
744
+ "commands",
745
+ "members",
746
+ "remove.js"
747
+ ]
591
748
  }
592
749
  },
593
- "version": "0.0.3"
750
+ "version": "1.0.0"
594
751
  }
package/package.json CHANGED
@@ -1,10 +1,17 @@
1
1
  {
2
2
  "name": "slickenv",
3
- "version": "0.0.3",
4
- "description": "CLI tool for securely managing, syncing, and versioning .env files",
3
+ "version": "1.0.0",
4
+ "description": "Securely manage, sync, and version .env files across your team with end-to-end encryption",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
+ "author": {
8
+ "name": "SlickSpender",
9
+ "url": "https://slickspender.com"
10
+ },
7
11
  "homepage": "https://env.slickspender.com",
12
+ "bugs": {
13
+ "url": "https://github.com/jjackofall/slickenv/issues"
14
+ },
8
15
  "repository": {
9
16
  "type": "git",
10
17
  "url": "https://github.com/jjackofall/slickenv.git",
@@ -19,6 +26,10 @@
19
26
  "sync",
20
27
  "versioning",
21
28
  "encryption",
29
+ "team",
30
+ "collaboration",
31
+ "aes-256",
32
+ "e2e-encryption",
22
33
  "slickenv",
23
34
  "slickspender"
24
35
  ],