@griffin-app/griffin-cli 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +111 -161
  2. package/dist/cli.js +34 -15
  3. package/dist/commands/env.d.ts +1 -22
  4. package/dist/commands/env.js +22 -109
  5. package/dist/commands/generate-key.js +16 -10
  6. package/dist/commands/hub/apply.js +58 -34
  7. package/dist/commands/hub/connect.js +16 -9
  8. package/dist/commands/hub/login.d.ts +1 -0
  9. package/dist/commands/hub/login.js +79 -0
  10. package/dist/commands/hub/logout.d.ts +6 -0
  11. package/dist/commands/hub/logout.js +16 -0
  12. package/dist/commands/hub/plan.js +38 -21
  13. package/dist/commands/hub/run.js +93 -57
  14. package/dist/commands/hub/runs.js +75 -42
  15. package/dist/commands/hub/status.js +18 -13
  16. package/dist/commands/init.js +32 -24
  17. package/dist/commands/local/run.js +30 -16
  18. package/dist/commands/validate.js +18 -17
  19. package/dist/core/apply.d.ts +2 -2
  20. package/dist/core/apply.js +36 -38
  21. package/dist/core/apply.test.js +71 -27
  22. package/dist/core/credentials.d.ts +36 -0
  23. package/dist/core/credentials.js +98 -0
  24. package/dist/core/credentials.test.d.ts +1 -0
  25. package/dist/core/credentials.test.js +137 -0
  26. package/dist/core/diff.d.ts +7 -6
  27. package/dist/core/diff.js +2 -1
  28. package/dist/core/diff.test.js +44 -20
  29. package/dist/core/discovery.d.ts +2 -3
  30. package/dist/core/discovery.js +3 -10
  31. package/dist/core/plan-diff.d.ts +5 -6
  32. package/dist/core/plan-diff.js +6 -6
  33. package/dist/core/sdk.d.ts +5 -9
  34. package/dist/core/sdk.js +23 -15
  35. package/dist/core/variables.js +13 -0
  36. package/dist/index.d.ts +8 -3
  37. package/dist/index.js +6 -2
  38. package/dist/resolve.d.ts +3 -0
  39. package/dist/resolve.js +9 -0
  40. package/dist/schemas/credentials.d.ts +24 -0
  41. package/dist/schemas/credentials.js +23 -0
  42. package/dist/schemas/state.d.ts +5 -5
  43. package/dist/schemas/state.js +5 -7
  44. package/dist/test-runner.js +18 -22
  45. package/dist/utils/console.d.ts +5 -0
  46. package/dist/utils/console.js +5 -0
  47. package/dist/utils/sdk-error.d.ts +8 -0
  48. package/dist/utils/sdk-error.js +114 -0
  49. package/dist/utils/terminal.d.ts +100 -0
  50. package/dist/utils/terminal.js +148 -0
  51. package/package.json +9 -4
package/README.md CHANGED
@@ -35,18 +35,12 @@ This creates `.griffin/state.json` which tracks:
35
35
 
36
36
  Override project ID with `--project <name>`.
37
37
 
38
- ### 2. Configure Targets
39
-
40
- Add targets to your local environment:
41
-
42
- ```bash
43
- griffin local config add-target --env local --key api --url http://localhost:3000
44
- ```
38
+ ### 2. View Environments
45
39
 
46
40
  View configured environments:
47
41
 
48
42
  ```bash
49
- griffin local config list
43
+ griffin env list
50
44
  ```
51
45
 
52
46
  ### 3. Create Test Plans
@@ -56,10 +50,10 @@ Create test files in `__griffin__/` directories. These files export test plans t
56
50
  ### 4. Run Tests Locally
57
51
 
58
52
  ```bash
59
- griffin local run --env local
53
+ griffin local run local
60
54
  ```
61
55
 
62
- Executes tests locally against configured targets.
56
+ Executes tests locally using variables from `variables.yaml` for the specified environment.
63
57
 
64
58
  ### 5. Connect to Hub (Optional)
65
59
 
@@ -71,32 +65,35 @@ griffin hub connect --url https://hub.example.com --token <token>
71
65
 
72
66
  ```bash
73
67
  griffin hub plan
68
+ griffin hub plan production
74
69
  ```
75
70
 
76
- Shows what will be created, updated, or deleted on the hub.
71
+ Shows what will be created, updated, or deleted on the hub for the specified environment.
77
72
 
78
73
  ### 7. Apply to Hub
79
74
 
80
75
  ```bash
81
76
  griffin hub apply
77
+ griffin hub apply production
82
78
  ```
83
79
 
84
- Syncs plans to the hub.
80
+ Syncs plans to the hub for the specified environment.
85
81
 
86
82
  ### 8. Trigger Hub Run
87
83
 
88
84
  ```bash
89
- griffin hub run --plan <name> --env production
85
+ griffin hub run production --plan <name>
90
86
  ```
91
87
 
92
- Triggers a plan execution on the hub.
88
+ Triggers a plan execution on the hub in the specified environment.
93
89
 
94
90
  ## Commands
95
91
 
96
- Commands are organized into three groups:
92
+ Commands are organized into four groups:
97
93
 
98
94
  - **Top-level**: Project initialization and utilities
99
- - **local**: Local test execution and configuration
95
+ - **env**: Environment management
96
+ - **local**: Local test execution
100
97
  - **hub**: Hub operations (plan sync, remote execution)
101
98
 
102
99
  ### Top-Level Commands
@@ -136,99 +133,82 @@ Generate a cryptographically secure API key for authentication.
136
133
  griffin generate-key
137
134
  ```
138
135
 
139
- ### Local Commands
140
-
141
- #### `griffin local run`
142
-
143
- Run tests locally against configured targets.
144
-
145
- **Options:**
146
-
147
- - `--env <name>` - Environment to run against (uses default if not specified)
136
+ ### Environment Commands
148
137
 
149
- **Example:**
150
-
151
- ```bash
152
- griffin local run
153
- griffin local run --env staging
154
- ```
138
+ #### `griffin env list`
155
139
 
156
- #### `griffin local config list`
157
-
158
- List all local environments and their targets.
140
+ List all available environments.
159
141
 
160
142
  **Example:**
161
143
 
162
144
  ```bash
163
- griffin local config list
145
+ griffin env list
164
146
  ```
165
147
 
166
- #### `griffin local config add-target`
148
+ Shows all configured environments with an asterisk (\*) marking the default environment.
167
149
 
168
- Add a target to a local environment.
150
+ ### Local Commands
169
151
 
170
- **Options:**
152
+ #### `griffin local run [env]`
171
153
 
172
- - `--env <name>` - Environment name (required)
173
- - `--key <key>` - Target key (required)
174
- - `--url <url>` - Target URL (required)
154
+ Run tests locally against an environment. Environment can be specified as a positional argument, or uses the default environment if omitted.
175
155
 
176
156
  **Example:**
177
157
 
178
158
  ```bash
179
- griffin local config add-target --env local --key api --url http://localhost:3000
180
- griffin local config add-target --env staging --key billing --url http://localhost:3001
159
+ griffin local run
160
+ griffin local run staging
181
161
  ```
182
162
 
183
- #### `griffin local config remove-target`
163
+ Variables are loaded from `variables.yaml` for the specified environment.
184
164
 
185
- Remove a target from a local environment.
165
+ ### Hub Commands
166
+
167
+ #### `griffin hub connect`
168
+
169
+ Configure hub connection settings. When a token is provided, it is stored in the user-level credentials file (`~/.griffin/credentials.json`) for secure, cross-project authentication.
186
170
 
187
171
  **Options:**
188
172
 
189
- - `--env <name>` - Environment name (required)
190
- - `--key <key>` - Target key (required)
173
+ - `--url <url>` - Hub URL (required)
174
+ - `--token <token>` - API authentication token (optional)
191
175
 
192
176
  **Example:**
193
177
 
194
178
  ```bash
195
- griffin local config remove-target --env local --key api
179
+ griffin hub connect --url https://hub.example.com --token abc123
196
180
  ```
197
181
 
198
- #### `griffin local config set-default-env`
182
+ #### `griffin hub login`
199
183
 
200
- Set the default environment for local runs.
201
-
202
- **Options:**
203
-
204
- - `--env <name>` - Environment name (required)
184
+ Authenticate with the hub using device authorization flow. The received token is stored in the user-level credentials file (`~/.griffin/credentials.json`) for secure access across all projects.
205
185
 
206
186
  **Example:**
207
187
 
208
188
  ```bash
209
- griffin local config set-default-env --env local
189
+ griffin hub login
210
190
  ```
211
191
 
212
- ### Hub Commands
192
+ After running this command, you'll be provided with a URL to complete authentication in your browser. Once authenticated, the token will be automatically saved.
213
193
 
214
- #### `griffin hub connect`
194
+ #### `griffin hub logout`
215
195
 
216
- Configure hub connection settings.
196
+ Remove stored credentials for the currently configured hub or all hubs.
217
197
 
218
198
  **Options:**
219
199
 
220
- - `--url <url>` - Hub URL (required)
221
- - `--token <token>` - API authentication token
200
+ - `--all` - Remove credentials for all hubs
222
201
 
223
202
  **Example:**
224
203
 
225
204
  ```bash
226
- griffin hub connect --url https://hub.example.com --token abc123
205
+ griffin hub logout
206
+ griffin hub logout --all
227
207
  ```
228
208
 
229
209
  #### `griffin hub status`
230
210
 
231
- Show hub connection status.
211
+ Show hub connection status, including whether credentials are configured.
232
212
 
233
213
  **Example:**
234
214
 
@@ -252,20 +232,20 @@ griffin hub runs
252
232
  griffin hub runs --plan health-check --limit 5
253
233
  ```
254
234
 
255
- #### `griffin hub plan`
235
+ #### `griffin hub plan [env]`
256
236
 
257
- Show what changes would be applied to the hub.
237
+ Show what changes would be applied to the hub. Environment can be specified as a positional argument, or uses the default environment if omitted.
258
238
 
259
239
  **Options:**
260
240
 
261
- - `--env <name>` - Environment to plan for (uses default if not specified)
262
241
  - `--json` - Output in JSON format
263
242
 
264
243
  **Example:**
265
244
 
266
245
  ```bash
267
246
  griffin hub plan
268
- griffin hub plan --env production --json
247
+ griffin hub plan production
248
+ griffin hub plan staging --json
269
249
  ```
270
250
 
271
251
  **Exit codes:**
@@ -274,88 +254,41 @@ griffin hub plan --env production --json
274
254
  - `1` - Error
275
255
  - `2` - Changes pending
276
256
 
277
- #### `griffin hub apply`
257
+ #### `griffin hub apply [env]`
278
258
 
279
- Apply changes to the hub.
259
+ Apply changes to the hub. Environment can be specified as a positional argument, or uses the default environment if omitted.
280
260
 
281
261
  **Options:**
282
262
 
283
- - `--env <name>` - Environment to apply to (uses default if not specified)
284
263
  - `--auto-approve` - Skip confirmation prompt
285
264
  - `--dry-run` - Show what would be done without making changes
265
+ - `--prune` - Delete plans on hub that don't exist locally
286
266
 
287
267
  **Example:**
288
268
 
289
269
  ```bash
290
270
  griffin hub apply
291
- griffin hub apply --env production --auto-approve
292
- griffin hub apply --dry-run
271
+ griffin hub apply production --auto-approve
272
+ griffin hub apply staging --dry-run
273
+ griffin hub apply production --prune
293
274
  ```
294
275
 
295
- #### `griffin hub run`
276
+ #### `griffin hub run <env>`
296
277
 
297
- Trigger a plan run on the hub.
278
+ Trigger a plan run on the hub in the specified environment.
298
279
 
299
280
  **Options:**
300
281
 
301
282
  - `--plan <name>` - Plan name to run (required)
302
- - `--env <name>` - Target environment (required)
303
283
  - `--wait` - Wait for run to complete
284
+ - `--force` - Run even if local plan differs from hub
304
285
 
305
286
  **Example:**
306
287
 
307
288
  ```bash
308
- griffin hub run --plan health-check --env production
309
- griffin hub run --plan health-check --env staging --wait
310
- ```
311
-
312
- #### `griffin hub config list`
313
-
314
- List all hub target configurations.
315
-
316
- **Options:**
317
-
318
- - `--org <id>` - Filter by organization ID
319
- - `--env <name>` - Filter by environment name
320
-
321
- **Example:**
322
-
323
- ```bash
324
- griffin hub config list
325
- griffin hub config list --org acme --env production
326
- ```
327
-
328
- #### `griffin hub config add-target`
329
-
330
- Add a target to hub configuration.
331
-
332
- **Options:**
333
-
334
- - `--org <id>` - Organization ID (required)
335
- - `--env <name>` - Environment name (required)
336
- - `--key <key>` - Target key (required)
337
- - `--url <url>` - Target URL (required)
338
-
339
- **Example:**
340
-
341
- ```bash
342
- griffin hub config add-target --org acme --env production --key api --url https://api.example.com
343
- ```
344
-
345
- #### `griffin hub config remove-target`
346
-
347
- Remove a target from hub configuration.
348
-
349
- **Options:**
350
-
351
- - `--org <id>` - Organization ID (required)
352
- - `--env <name>` - Environment name (required)
353
- - `--key <key>` - Target key (required)
354
-
355
- **Example:**
356
-
357
- ```bash
358
- griffin hub config remove-target --org acme --env production --key api
289
+ griffin hub run production --plan health-check
290
+ griffin hub run staging --plan health-check --wait
291
+ griffin hub run production --plan api-check --force
359
292
  ```
360
293
 
361
294
  ## Configuration
@@ -366,59 +299,80 @@ griffin hub config remove-target --org acme --env production --key api
366
299
 
367
300
  ### State File
368
301
 
369
- Griffin stores configuration in `.griffin/state.json`:
302
+ Griffin stores project configuration in `.griffin/state.json`:
370
303
 
371
304
  ```json
372
305
  {
373
- "stateVersion": 3,
306
+ "stateVersion": 1,
374
307
  "projectId": "my-project",
375
308
  "environments": {
376
- "local": {
377
- "targets": {
378
- "api": "http://localhost:3000",
379
- "billing": "http://localhost:3001"
380
- }
381
- }
309
+ "local": {}
382
310
  },
383
311
  "defaultEnvironment": "local",
384
- "runner": {
312
+ "hub": {
385
313
  "baseUrl": "https://hub.example.com",
386
- "apiToken": "..."
314
+ "clientId": "..."
387
315
  },
388
316
  "discovery": {
389
317
  "pattern": "**/__griffin__/*.{ts,js}",
390
318
  "ignore": ["node_modules/**", "dist/**"]
391
- },
392
- "plans": {
393
- "local": []
394
319
  }
395
320
  }
396
321
  ```
397
322
 
398
- **Important:** Add `.griffin/` to `.gitignore` as it contains local state and potentially sensitive tokens.
323
+ **Important:** Add `.griffin/` to `.gitignore` as it contains local project state.
399
324
 
400
- ## Environments and Targets
325
+ ### Credentials File
401
326
 
402
- Griffin uses environments to organize target configurations. Each environment contains multiple named targets (key-value pairs of target keys to URLs).
327
+ Griffin stores user-level authentication credentials in `~/.griffin/credentials.json`:
403
328
 
404
- **Local environments:**
329
+ ```json
330
+ {
331
+ "version": 1,
332
+ "hubs": {
333
+ "https://hub.example.com": {
334
+ "token": "...",
335
+ "updatedAt": "2024-01-24T12:00:00.000Z"
336
+ }
337
+ }
338
+ }
339
+ ```
340
+
341
+ This file is automatically created and managed by the CLI when you use `griffin hub login` or `griffin hub connect --token <token>`. Credentials are stored per-hub URL and are available across all projects on your system.
342
+
343
+ **Security:** The credentials file is created with restricted permissions (0600) to ensure only the owner can read/write.
344
+
345
+ ## Environments and Variables
405
346
 
406
- - Defined in `.griffin/state.json`
407
- - Used for local test execution
408
- - Managed via `griffin local config` commands
347
+ Griffin uses environments to organize test configurations. Each environment maps to a section in `variables.yaml` which contains environment-specific variable values.
348
+
349
+ **Example `variables.yaml`:**
350
+
351
+ ```yaml
352
+ environments:
353
+ local:
354
+ api_host: "localhost:3000"
355
+ api_key: "local-test-key"
356
+ staging:
357
+ api_host: "staging.example.com"
358
+ api_key: "staging-key"
359
+ production:
360
+ api_host: "api.example.com"
361
+ api_key: "prod-key"
362
+ ```
409
363
 
410
364
  **Example workflow:**
411
365
 
412
366
  ```bash
413
- # Create local environment with targets
414
- griffin local config add-target --env local --key api --url http://localhost:3000
415
- griffin local config add-target --env local --key billing --url http://localhost:3001
367
+ # List available environments
368
+ griffin env list
416
369
 
417
- # Set default environment
418
- griffin local config set-default-env --env local
370
+ # Run tests against different environments
371
+ griffin local run local
372
+ griffin local run staging
419
373
 
420
- # Run tests using default environment
421
- griffin local run
374
+ # Sync to hub for specific environment
375
+ griffin hub apply production
422
376
  ```
423
377
 
424
378
  ## Test Plan Discovery
@@ -448,10 +402,7 @@ Required endpoints:
448
402
  - `GET /plan` - List plans
449
403
  - `GET /runs` - List runs
450
404
  - `GET /runs/:id` - Get run details
451
- - `POST /runs/trigger/:id` - Trigger run
452
- - `GET /config` - List configurations
453
- - `PUT /config/:org/:env/targets/:key` - Set target
454
- - `DELETE /config/:org/:env/targets/:key` - Delete target
405
+ - `POST /runs/trigger/:planId` - Trigger run
455
406
 
456
407
  ## Development
457
408
 
@@ -476,16 +427,15 @@ griffin-cli/
476
427
  ├── src/
477
428
  │ ├── commands/ # Command implementations
478
429
  │ │ ├── local/ # Local execution commands
479
- │ │ │ ├── run.ts
480
- │ │ │ └── config.ts
430
+ │ │ │ └── run.ts
481
431
  │ │ ├── hub/ # Hub operation commands
482
432
  │ │ │ ├── connect.ts
483
433
  │ │ │ ├── status.ts
484
434
  │ │ │ ├── runs.ts
485
435
  │ │ │ ├── plan.ts
486
436
  │ │ │ ├── apply.ts
487
- │ │ │ ├── run.ts
488
- │ │ │ └── config.ts
437
+ │ │ │ └── run.ts
438
+ │ │ ├── env.ts # Environment commands
489
439
  │ │ ├── init.ts
490
440
  │ │ ├── validate.ts
491
441
  │ │ └── generate-key.ts
@@ -495,9 +445,9 @@ griffin-cli/
495
445
  │ │ ├── diff.ts # Diff computation
496
446
  │ │ ├── discovery.ts # Plan discovery
497
447
  │ │ ├── state.ts # State management
448
+ │ │ ├── variables.ts # Variable resolution
498
449
  │ │ └── project.ts # Project detection
499
450
  │ ├── schemas/ # Type definitions
500
- │ │ ├── payload.ts # Plan payload schemas
501
451
  │ │ └── state.ts # State file schemas
502
452
  │ ├── cli.ts # CLI entry point
503
453
  │ └── index.ts # Public API exports
package/dist/cli.js CHANGED
@@ -3,6 +3,7 @@ import { Command } from "commander";
3
3
  import { executeInit } from "./commands/init.js";
4
4
  import { executeValidate } from "./commands/validate.js";
5
5
  import { executeGenerateKey } from "./commands/generate-key.js";
6
+ import { executeEnvList } from "./commands/env.js";
6
7
  // Local commands
7
8
  import { executeRunLocal } from "./commands/local/run.js";
8
9
  // Hub commands
@@ -12,6 +13,8 @@ import { executeRuns } from "./commands/hub/runs.js";
12
13
  import { executePlan } from "./commands/hub/plan.js";
13
14
  import { executeApply } from "./commands/hub/apply.js";
14
15
  import { executeRun } from "./commands/hub/run.js";
16
+ import { executeLogin } from "./commands/hub/login.js";
17
+ import { executeLogout } from "./commands/hub/logout.js";
15
18
  const program = new Command();
16
19
  program
17
20
  .name("griffin")
@@ -37,14 +40,21 @@ program
37
40
  .action(async () => {
38
41
  await executeGenerateKey();
39
42
  });
43
+ // Environment command group
44
+ const env = program.command("env").description("Manage environments");
45
+ env
46
+ .command("list")
47
+ .description("List all available environments")
48
+ .action(async () => {
49
+ await executeEnvList();
50
+ });
40
51
  // Local command group
41
52
  const local = program.command("local").description("Local test execution");
42
53
  local
43
- .command("run")
54
+ .command("run [env]")
44
55
  .description("Run tests locally against an environment")
45
- .option("--env <name>", "Environment to run against (uses default if not specified)")
46
- .action(async (options) => {
47
- await executeRunLocal(options);
56
+ .action(async (env, options) => {
57
+ await executeRunLocal({ env });
48
58
  });
49
59
  // Hub command group
50
60
  const hub = program.command("hub").description("Griffin Hub operations");
@@ -74,32 +84,41 @@ hub
74
84
  });
75
85
  });
76
86
  hub
77
- .command("plan")
87
+ .command("plan [env]")
78
88
  .description("Show what changes would be applied")
79
- .option("--env <name>", "Environment to plan for (uses default if not specified)")
80
89
  .option("--json", "Output in JSON format")
81
- .action(async (options) => {
82
- await executePlan(options);
90
+ .action(async (env, options) => {
91
+ await executePlan({ ...options, env });
83
92
  });
84
93
  hub
85
- .command("apply")
94
+ .command("apply [env]")
86
95
  .description("Apply changes to the hub")
87
- .option("--env <name>", "Environment to apply to (uses default if not specified)")
88
96
  .option("--auto-approve", "Skip confirmation prompt")
89
97
  .option("--dry-run", "Show what would be done without making changes")
90
98
  .option("--prune", "Delete plans on hub that don't exist locally")
91
- .action(async (options) => {
92
- await executeApply(options);
99
+ .action(async (env, options) => {
100
+ await executeApply({ ...options, env });
93
101
  });
94
102
  hub
95
- .command("run")
103
+ .command("run <env>")
96
104
  .description("Trigger a plan run on the hub")
97
105
  .requiredOption("--plan <name>", "Plan name to run")
98
- .requiredOption("--env <name>", "Target environment")
99
106
  .option("--wait", "Wait for run to complete")
100
107
  .option("--force", "Run even if local plan differs from hub")
108
+ .action(async (env, options) => {
109
+ await executeRun({ ...options, env });
110
+ });
111
+ hub
112
+ .command("login")
113
+ .description("Login to the hub")
114
+ .action(async () => {
115
+ await executeLogin();
116
+ });
117
+ hub
118
+ .command("logout")
119
+ .description("Remove stored credentials")
101
120
  .action(async (options) => {
102
- await executeRun(options);
121
+ await executeLogout(options);
103
122
  });
104
123
  // Parse arguments
105
124
  program.parse();
@@ -1,25 +1,4 @@
1
- export interface EnvAddOptions {
2
- baseUrl: string;
3
- }
4
- export interface EnvRemoveOptions {
5
- name: string;
6
- }
7
- export interface EnvDefaultOptions {
8
- name: string;
9
- }
10
1
  /**
11
- * List all environments
2
+ * List all available environments
12
3
  */
13
4
  export declare function executeEnvList(): Promise<void>;
14
- /**
15
- * Add or update an environment
16
- */
17
- export declare function executeEnvAdd(name: string, options: EnvAddOptions): Promise<void>;
18
- /**
19
- * Remove an environment
20
- */
21
- export declare function executeEnvRemove(name: string): Promise<void>;
22
- /**
23
- * Set default environment
24
- */
25
- export declare function executeEnvDefault(name: string): Promise<void>;