@quonfig/cli 0.0.4 → 0.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.
- package/README.md +213 -33
- package/dist/commands/config-schema.d.ts +10 -0
- package/dist/commands/config-schema.js +165 -0
- package/dist/commands/create.js +22 -1
- package/dist/commands/info.js +17 -2
- package/dist/commands/pull.js +16 -1
- package/dist/commands/set-default.js +78 -15
- package/dist/commands/set-rollout.d.ts +19 -0
- package/dist/commands/set-rollout.js +260 -0
- package/oclif.manifest.json +183 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ $ npm install -g @quonfig/cli
|
|
|
14
14
|
$ qfg COMMAND
|
|
15
15
|
running command...
|
|
16
16
|
$ qfg (--version)
|
|
17
|
-
@quonfig/cli/0.0.
|
|
17
|
+
@quonfig/cli/0.0.5 linux-x64 node-v24.4.1
|
|
18
18
|
$ qfg --help [COMMAND]
|
|
19
19
|
USAGE
|
|
20
20
|
$ qfg COMMAND
|
|
@@ -25,6 +25,7 @@ USAGE
|
|
|
25
25
|
# Commands
|
|
26
26
|
|
|
27
27
|
<!-- commands -->
|
|
28
|
+
* [`qfg config-schema`](#qfg-config-schema)
|
|
28
29
|
* [`qfg create NAME`](#qfg-create-name)
|
|
29
30
|
* [`qfg download`](#qfg-download)
|
|
30
31
|
* [`qfg generate`](#qfg-generate)
|
|
@@ -43,15 +44,45 @@ USAGE
|
|
|
43
44
|
* [`qfg schema NAME`](#qfg-schema-name)
|
|
44
45
|
* [`qfg serve DATA-FILE`](#qfg-serve-data-file)
|
|
45
46
|
* [`qfg set-default [NAME]`](#qfg-set-default-name)
|
|
47
|
+
* [`qfg set-rollout [NAME]`](#qfg-set-rollout-name)
|
|
46
48
|
* [`qfg sync`](#qfg-sync)
|
|
47
49
|
* [`qfg verify [PATH]`](#qfg-verify-path)
|
|
48
50
|
* [`qfg whoami`](#qfg-whoami)
|
|
49
51
|
* [`qfg workspace`](#qfg-workspace)
|
|
50
52
|
* [`qfg workspace bootstrap`](#qfg-workspace-bootstrap)
|
|
51
53
|
|
|
54
|
+
## `qfg config-schema`
|
|
55
|
+
|
|
56
|
+
Print the config file format reference: rules engine, operators, targeting criteria, segments, and weighted rollouts. Use --json-schema for the machine-readable JSON Schema document.
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
USAGE
|
|
60
|
+
$ qfg config-schema [--json] [--interactive] [--no-color] [--verbose] [--json-schema]
|
|
61
|
+
|
|
62
|
+
FLAGS
|
|
63
|
+
--json-schema Output the full JSON Schema document for config files instead of the human-readable reference
|
|
64
|
+
|
|
65
|
+
GLOBAL FLAGS
|
|
66
|
+
--[no-]interactive Force interactive mode
|
|
67
|
+
--json Format output as json.
|
|
68
|
+
--no-color Do not colorize output
|
|
69
|
+
--verbose Verbose output
|
|
70
|
+
|
|
71
|
+
DESCRIPTION
|
|
72
|
+
Print the config file format reference: rules engine, operators, targeting criteria, segments, and weighted rollouts.
|
|
73
|
+
Use --json-schema for the machine-readable JSON Schema document.
|
|
74
|
+
|
|
75
|
+
EXAMPLES
|
|
76
|
+
$ qfg config-schema # human-readable operator reference + examples
|
|
77
|
+
|
|
78
|
+
$ qfg config-schema --json-schema # full JSON Schema document (copy into your editor)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
_See code: [src/commands/config-schema.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/config-schema.ts)_
|
|
82
|
+
|
|
52
83
|
## `qfg create NAME`
|
|
53
84
|
|
|
54
|
-
Create a new
|
|
85
|
+
Create a new feature flag, config value, or other item.
|
|
55
86
|
|
|
56
87
|
```
|
|
57
88
|
USAGE
|
|
@@ -80,7 +111,26 @@ GLOBAL FLAGS
|
|
|
80
111
|
--verbose Verbose output
|
|
81
112
|
|
|
82
113
|
DESCRIPTION
|
|
83
|
-
Create a new
|
|
114
|
+
Create a new feature flag, config value, or other item.
|
|
115
|
+
|
|
116
|
+
Use --type to specify the kind of item:
|
|
117
|
+
boolean-flag On/off feature flag (sendToClientSdk defaults to true; best for gradual rollouts)
|
|
118
|
+
string A string configuration value
|
|
119
|
+
int An integer configuration value
|
|
120
|
+
double A floating-point configuration value
|
|
121
|
+
string-list A comma-separated list of strings
|
|
122
|
+
json An arbitrary JSON blob
|
|
123
|
+
boolean A plain boolean (not a feature flag)
|
|
124
|
+
|
|
125
|
+
This sets the global default value. Override per-environment with:
|
|
126
|
+
qfg set-default my.flag --environment production --value true
|
|
127
|
+
|
|
128
|
+
For a percentage rollout (gradual rollout / A/B test / canary deploy), use:
|
|
129
|
+
qfg set-rollout my.flag --environment production --true-percent 20
|
|
130
|
+
|
|
131
|
+
Or edit the JSON config file directly for complex targeting rules:
|
|
132
|
+
qfg config-schema # full operator reference + examples
|
|
133
|
+
qfg pull --dir ./config # clone workspace, then edit JSON and git push
|
|
84
134
|
|
|
85
135
|
EXAMPLES
|
|
86
136
|
$ qfg create my.new.flag --type boolean-flag
|
|
@@ -94,9 +144,13 @@ EXAMPLES
|
|
|
94
144
|
$ qfg create my.new.string --type string --env-var=MY_ENV_VAR_NAME
|
|
95
145
|
|
|
96
146
|
$ qfg create my.new.string --type json --value="{\"key\": \"value\"}"
|
|
147
|
+
|
|
148
|
+
# After creating a flag, set a 20% rollout in production:
|
|
149
|
+
|
|
150
|
+
$ qfg set-rollout my.new.flag --environment production --true-percent 20
|
|
97
151
|
```
|
|
98
152
|
|
|
99
|
-
_See code: [src/commands/create.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
153
|
+
_See code: [src/commands/create.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/create.ts)_
|
|
100
154
|
|
|
101
155
|
## `qfg download`
|
|
102
156
|
|
|
@@ -129,7 +183,7 @@ EXAMPLES
|
|
|
129
183
|
$ qfg download --environment=test --sdk-key=YOUR_SDK_KEY
|
|
130
184
|
```
|
|
131
185
|
|
|
132
|
-
_See code: [src/commands/download.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
186
|
+
_See code: [src/commands/download.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/download.ts)_
|
|
133
187
|
|
|
134
188
|
## `qfg generate`
|
|
135
189
|
|
|
@@ -199,7 +253,7 @@ EXAMPLES
|
|
|
199
253
|
$ qfg generate --targets node-ts -o ./dist # combine with targets
|
|
200
254
|
```
|
|
201
255
|
|
|
202
|
-
_See code: [src/commands/generate.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
256
|
+
_See code: [src/commands/generate.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/generate.ts)_
|
|
203
257
|
|
|
204
258
|
## `qfg generate-new-hex-key`
|
|
205
259
|
|
|
@@ -222,7 +276,7 @@ EXAMPLES
|
|
|
222
276
|
$ qfg generate-new-hex-key
|
|
223
277
|
```
|
|
224
278
|
|
|
225
|
-
_See code: [src/commands/generate-new-hex-key.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
279
|
+
_See code: [src/commands/generate-new-hex-key.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/generate-new-hex-key.ts)_
|
|
226
280
|
|
|
227
281
|
## `qfg get [NAME]`
|
|
228
282
|
|
|
@@ -254,11 +308,11 @@ EXAMPLES
|
|
|
254
308
|
$ qfg get my.config.name --environment=production
|
|
255
309
|
```
|
|
256
310
|
|
|
257
|
-
_See code: [src/commands/get.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
311
|
+
_See code: [src/commands/get.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/get.ts)_
|
|
258
312
|
|
|
259
313
|
## `qfg info [NAME]`
|
|
260
314
|
|
|
261
|
-
Show
|
|
315
|
+
Show current values, rules, and evaluation stats for a flag or config.
|
|
262
316
|
|
|
263
317
|
```
|
|
264
318
|
USAGE
|
|
@@ -278,13 +332,27 @@ GLOBAL FLAGS
|
|
|
278
332
|
--verbose Verbose output
|
|
279
333
|
|
|
280
334
|
DESCRIPTION
|
|
281
|
-
Show
|
|
335
|
+
Show current values, rules, and evaluation stats for a flag or config.
|
|
336
|
+
|
|
337
|
+
Output shows the value for each environment:
|
|
338
|
+
- A simple value (true / false / "hello") means a single unconditional rule.
|
|
339
|
+
- "[see rules]" means the environment has targeting rules or a percentage rollout.
|
|
340
|
+
- "[inherit]" means the environment falls back to the Default value.
|
|
341
|
+
|
|
342
|
+
Percentage rollouts are displayed as "20.0% true, 80.0% false".
|
|
343
|
+
Evaluation counts for the past 24 hours are included by default.
|
|
344
|
+
|
|
345
|
+
Related commands:
|
|
346
|
+
qfg set-default my.flag --environment production --value true # set a scalar fallback
|
|
347
|
+
qfg set-rollout my.flag --environment production --true-percent 20 # set a % rollout
|
|
282
348
|
|
|
283
349
|
EXAMPLES
|
|
284
350
|
$ qfg info my.config.name
|
|
351
|
+
|
|
352
|
+
$ qfg info my.config.name --exclude-evaluations # skip 24h stats
|
|
285
353
|
```
|
|
286
354
|
|
|
287
|
-
_See code: [src/commands/info.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
355
|
+
_See code: [src/commands/info.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/info.ts)_
|
|
288
356
|
|
|
289
357
|
## `qfg init [DIRECTORY]`
|
|
290
358
|
|
|
@@ -322,7 +390,7 @@ EXAMPLES
|
|
|
322
390
|
$ qfg init --dry-run
|
|
323
391
|
```
|
|
324
392
|
|
|
325
|
-
_See code: [src/commands/init.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
393
|
+
_See code: [src/commands/init.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/init.ts)_
|
|
326
394
|
|
|
327
395
|
## `qfg interactive`
|
|
328
396
|
|
|
@@ -340,7 +408,7 @@ EXAMPLES
|
|
|
340
408
|
$ qfg
|
|
341
409
|
```
|
|
342
410
|
|
|
343
|
-
_See code: [src/commands/interactive.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
411
|
+
_See code: [src/commands/interactive.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/interactive.ts)_
|
|
344
412
|
|
|
345
413
|
## `qfg list`
|
|
346
414
|
|
|
@@ -377,7 +445,7 @@ EXAMPLES
|
|
|
377
445
|
$ qfg list --feature-flags
|
|
378
446
|
```
|
|
379
447
|
|
|
380
|
-
_See code: [src/commands/list.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
448
|
+
_See code: [src/commands/list.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/list.ts)_
|
|
381
449
|
|
|
382
450
|
## `qfg login`
|
|
383
451
|
|
|
@@ -405,7 +473,7 @@ EXAMPLES
|
|
|
405
473
|
$ qfg login --profile myprofile
|
|
406
474
|
```
|
|
407
475
|
|
|
408
|
-
_See code: [src/commands/login.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
476
|
+
_See code: [src/commands/login.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/login.ts)_
|
|
409
477
|
|
|
410
478
|
## `qfg logout`
|
|
411
479
|
|
|
@@ -428,7 +496,7 @@ EXAMPLES
|
|
|
428
496
|
$ qfg logout
|
|
429
497
|
```
|
|
430
498
|
|
|
431
|
-
_See code: [src/commands/logout.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
499
|
+
_See code: [src/commands/logout.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/logout.ts)_
|
|
432
500
|
|
|
433
501
|
## `qfg mcp`
|
|
434
502
|
|
|
@@ -461,7 +529,7 @@ EXAMPLES
|
|
|
461
529
|
$ qfg mcp --url http://local-app.quonfig-staging.com:3003/api/v1/mcp
|
|
462
530
|
```
|
|
463
531
|
|
|
464
|
-
_See code: [src/commands/mcp.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
532
|
+
_See code: [src/commands/mcp.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/mcp.ts)_
|
|
465
533
|
|
|
466
534
|
## `qfg override [NAME]`
|
|
467
535
|
|
|
@@ -500,7 +568,7 @@ EXAMPLES
|
|
|
500
568
|
$ qfg override my.double.config --value=3.14159
|
|
501
569
|
```
|
|
502
570
|
|
|
503
|
-
_See code: [src/commands/override.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
571
|
+
_See code: [src/commands/override.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/override.ts)_
|
|
504
572
|
|
|
505
573
|
## `qfg profile`
|
|
506
574
|
|
|
@@ -523,11 +591,11 @@ EXAMPLES
|
|
|
523
591
|
$ qfg profile
|
|
524
592
|
```
|
|
525
593
|
|
|
526
|
-
_See code: [src/commands/profile.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
594
|
+
_See code: [src/commands/profile.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/profile.ts)_
|
|
527
595
|
|
|
528
596
|
## `qfg pull`
|
|
529
597
|
|
|
530
|
-
Clone or update a local
|
|
598
|
+
Clone or update a local copy of your workspace config files.
|
|
531
599
|
|
|
532
600
|
```
|
|
533
601
|
USAGE
|
|
@@ -544,7 +612,22 @@ GLOBAL FLAGS
|
|
|
544
612
|
--verbose Verbose output
|
|
545
613
|
|
|
546
614
|
DESCRIPTION
|
|
547
|
-
Clone or update a local
|
|
615
|
+
Clone or update a local copy of your workspace config files.
|
|
616
|
+
|
|
617
|
+
Use this when you need to edit flag JSON directly — for complex targeting rules,
|
|
618
|
+
multi-rule configs, or anything beyond a single scalar value.
|
|
619
|
+
|
|
620
|
+
For the config file format, operator reference, and examples:
|
|
621
|
+
qfg config-schema # human-readable reference
|
|
622
|
+
qfg config-schema --json-schema # machine-readable JSON Schema
|
|
623
|
+
|
|
624
|
+
After editing files:
|
|
625
|
+
qfg verify <dir> # validate JSON before pushing
|
|
626
|
+
git -C <dir> add -A && git -C <dir> commit -m "feat: ..." && git -C <dir> push
|
|
627
|
+
|
|
628
|
+
CLI shortcuts (no JSON editing needed for simple cases):
|
|
629
|
+
qfg set-rollout my.flag --environment production --true-percent 20
|
|
630
|
+
qfg set-default my.flag --environment production --value true
|
|
548
631
|
|
|
549
632
|
EXAMPLES
|
|
550
633
|
$ qfg pull --dir ./our-config
|
|
@@ -552,7 +635,7 @@ EXAMPLES
|
|
|
552
635
|
$ qfg pull # uses QUONFIG_DIR env var
|
|
553
636
|
```
|
|
554
637
|
|
|
555
|
-
_See code: [src/commands/pull.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
638
|
+
_See code: [src/commands/pull.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/pull.ts)_
|
|
556
639
|
|
|
557
640
|
## `qfg schema NAME`
|
|
558
641
|
|
|
@@ -590,7 +673,7 @@ EXAMPLES
|
|
|
590
673
|
$ qfg schema my-schema --set-json-schema=@schemas/my-schema.json --protected
|
|
591
674
|
```
|
|
592
675
|
|
|
593
|
-
_See code: [src/commands/schema.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
676
|
+
_See code: [src/commands/schema.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/schema.ts)_
|
|
594
677
|
|
|
595
678
|
## `qfg serve DATA-FILE`
|
|
596
679
|
|
|
@@ -626,11 +709,11 @@ EXAMPLES
|
|
|
626
709
|
$ qfg serve ./quonfig.test.588.config.json --port=3099
|
|
627
710
|
```
|
|
628
711
|
|
|
629
|
-
_See code: [src/commands/serve.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
712
|
+
_See code: [src/commands/serve.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/serve.ts)_
|
|
630
713
|
|
|
631
714
|
## `qfg set-default [NAME]`
|
|
632
715
|
|
|
633
|
-
Set
|
|
716
|
+
Set the unconditional fallback value for a flag or config in a specific environment.
|
|
634
717
|
|
|
635
718
|
```
|
|
636
719
|
USAGE
|
|
@@ -658,19 +741,116 @@ GLOBAL FLAGS
|
|
|
658
741
|
--verbose Verbose output
|
|
659
742
|
|
|
660
743
|
DESCRIPTION
|
|
661
|
-
Set
|
|
744
|
+
Set the unconditional fallback value for a flag or config in a specific environment.
|
|
745
|
+
|
|
746
|
+
This updates the catch-all rule — the value users receive when NO targeting rule matches.
|
|
747
|
+
Any targeting rules or percentage rollouts you have configured are NOT affected; they
|
|
748
|
+
continue to fire before this fallback is evaluated.
|
|
749
|
+
|
|
750
|
+
"Other rules still apply" means: if you have rules targeting specific users, segments,
|
|
751
|
+
or properties, those rules still take priority. This command only changes what everyone
|
|
752
|
+
else sees.
|
|
753
|
+
|
|
754
|
+
To set a percentage rollout (gradual rollout / A/B test / canary deploy) instead:
|
|
755
|
+
qfg set-rollout my.flag --environment production --true-percent 20
|
|
756
|
+
|
|
757
|
+
To see all current values and rules for a flag:
|
|
758
|
+
qfg info my.flag
|
|
662
759
|
|
|
663
760
|
EXAMPLES
|
|
664
|
-
$ qfg set-default my.flag.name
|
|
761
|
+
$ qfg set-default my.flag.name # prompts for value and env
|
|
665
762
|
|
|
666
763
|
$ qfg set-default my.flag.name --value=true --environment=staging
|
|
667
764
|
|
|
765
|
+
$ qfg set-default my.flag.name --value=false --environment=production # kill-switch: turn off for everyone
|
|
766
|
+
|
|
668
767
|
$ qfg set-default my.flag.name --value=true --secret
|
|
669
768
|
|
|
670
769
|
$ qfg set-default my.config.name --env-var=MY_ENV_VAR_NAME --environment=production
|
|
770
|
+
|
|
771
|
+
# For a percentage rollout, use set-rollout instead:
|
|
772
|
+
|
|
773
|
+
$ qfg set-rollout my.flag.name --environment production --true-percent 20
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
_See code: [src/commands/set-default.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/set-default.ts)_
|
|
777
|
+
|
|
778
|
+
## `qfg set-rollout [NAME]`
|
|
779
|
+
|
|
780
|
+
Configure a percentage rollout (gradual rollout / A/B test / canary deploy) for a flag.
|
|
781
|
+
|
|
782
|
+
```
|
|
783
|
+
USAGE
|
|
784
|
+
$ qfg set-rollout [NAME] [--json] [--interactive] [--no-color] [--verbose] [-p <value>] [--environment <value>]
|
|
785
|
+
[--hash-by <value>] [--true-percent <value>] [--weights <value>] [--confirm]
|
|
786
|
+
|
|
787
|
+
ARGUMENTS
|
|
788
|
+
NAME config/feature-flag/etc. name
|
|
789
|
+
|
|
790
|
+
FLAGS
|
|
791
|
+
--confirm skip the interactive confirmation prompt (useful for scripts and agents)
|
|
792
|
+
--environment=<value> environment to update (e.g. production, staging)
|
|
793
|
+
--hash-by=<value> [default: user.key] user property used to assign buckets (default: user.key)
|
|
794
|
+
--true-percent=<value> percentage of users that receive true (0–100). Remaining users receive false. Boolean flags
|
|
795
|
+
only.
|
|
796
|
+
--weights=<value> comma-separated "value:percent" pairs that must sum to 100 (e.g. "true:20,false:80" or
|
|
797
|
+
"red:33,green:33,blue:34")
|
|
798
|
+
|
|
799
|
+
GLOBAL FLAGS
|
|
800
|
+
-p, --profile=<value> Profile to use (defaults to ENV var QUONFIG_PROFILE or "default")
|
|
801
|
+
--[no-]interactive Force interactive mode
|
|
802
|
+
--json Format output as json.
|
|
803
|
+
--no-color Do not colorize output
|
|
804
|
+
--verbose Verbose output
|
|
805
|
+
|
|
806
|
+
DESCRIPTION
|
|
807
|
+
Configure a percentage rollout (gradual rollout / A/B test / canary deploy) for a flag.
|
|
808
|
+
|
|
809
|
+
The flag must already exist. Create it first if needed:
|
|
810
|
+
qfg create my.flag --type boolean-flag
|
|
811
|
+
|
|
812
|
+
Weights are specified as whole-number percentages (0–100). They must sum to 100.
|
|
813
|
+
|
|
814
|
+
For a boolean flag, use --true-percent to set the percentage of users that receive
|
|
815
|
+
true (the remainder automatically receive false):
|
|
816
|
+
qfg set-rollout my.flag --environment production --true-percent 20
|
|
817
|
+
→ 20% of users get true, 80% get false
|
|
818
|
+
|
|
819
|
+
For multi-value flags or custom splits, use --weights with a comma-separated list:
|
|
820
|
+
qfg set-rollout my.flag --environment production --weights "red:33,green:33,blue:34"
|
|
821
|
+
|
|
822
|
+
Hashing: users are bucketed by the value of hashByPropertyName (default: "user.key").
|
|
823
|
+
Use --hash-by to change which property drives the bucket assignment:
|
|
824
|
+
qfg set-rollout my.flag --environment production --true-percent 10 --hash-by user.id
|
|
825
|
+
|
|
826
|
+
For scripted / agent use, add --confirm to skip the interactive confirmation prompt.
|
|
827
|
+
|
|
828
|
+
To combine a rollout with segment targeting (e.g. beta ON, holdout OFF, everyone else 50/50),
|
|
829
|
+
you need to edit the JSON config file directly:
|
|
830
|
+
qfg config-schema # operator reference + worked multi-rule example
|
|
831
|
+
qfg pull --dir ./config # clone workspace to edit
|
|
832
|
+
|
|
833
|
+
To revert to a single value for everyone, use:
|
|
834
|
+
qfg set-default my.flag --environment production --value false
|
|
835
|
+
|
|
836
|
+
To inspect the current rollout:
|
|
837
|
+
qfg info my.flag
|
|
838
|
+
|
|
839
|
+
EXAMPLES
|
|
840
|
+
$ qfg set-rollout my.feature.flag --environment production --true-percent 20
|
|
841
|
+
|
|
842
|
+
$ qfg set-rollout my.feature.flag --environment staging --true-percent 50
|
|
843
|
+
|
|
844
|
+
$ qfg set-rollout my.feature.flag --environment production --true-percent 100 # full rollout
|
|
845
|
+
|
|
846
|
+
$ qfg set-rollout my.feature.flag --environment production --true-percent 0 # kill switch (all false)
|
|
847
|
+
|
|
848
|
+
$ qfg set-rollout my.variant.flag --environment production --weights "control:50,treatment:50"
|
|
849
|
+
|
|
850
|
+
$ qfg set-rollout my.variant.flag --environment production --weights "a:33,b:33,c:34" --hash-by user.id
|
|
671
851
|
```
|
|
672
852
|
|
|
673
|
-
_See code: [src/commands/set-
|
|
853
|
+
_See code: [src/commands/set-rollout.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/set-rollout.ts)_
|
|
674
854
|
|
|
675
855
|
## `qfg sync`
|
|
676
856
|
|
|
@@ -702,7 +882,7 @@ EXAMPLES
|
|
|
702
882
|
$ qfg sync --watch --dir ./our-config --interval 30
|
|
703
883
|
```
|
|
704
884
|
|
|
705
|
-
_See code: [src/commands/sync.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
885
|
+
_See code: [src/commands/sync.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/sync.ts)_
|
|
706
886
|
|
|
707
887
|
## `qfg verify [PATH]`
|
|
708
888
|
|
|
@@ -735,7 +915,7 @@ EXAMPLES
|
|
|
735
915
|
$ qfg verify --json
|
|
736
916
|
```
|
|
737
917
|
|
|
738
|
-
_See code: [src/commands/verify.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
918
|
+
_See code: [src/commands/verify.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/verify.ts)_
|
|
739
919
|
|
|
740
920
|
## `qfg whoami`
|
|
741
921
|
|
|
@@ -758,7 +938,7 @@ EXAMPLES
|
|
|
758
938
|
$ qfg whoami
|
|
759
939
|
```
|
|
760
940
|
|
|
761
|
-
_See code: [src/commands/whoami.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
941
|
+
_See code: [src/commands/whoami.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/whoami.ts)_
|
|
762
942
|
|
|
763
943
|
## `qfg workspace`
|
|
764
944
|
|
|
@@ -781,7 +961,7 @@ EXAMPLES
|
|
|
781
961
|
$ qfg workspace
|
|
782
962
|
```
|
|
783
963
|
|
|
784
|
-
_See code: [src/commands/workspace.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
964
|
+
_See code: [src/commands/workspace.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/workspace.ts)_
|
|
785
965
|
|
|
786
966
|
## `qfg workspace bootstrap`
|
|
787
967
|
|
|
@@ -814,7 +994,7 @@ EXAMPLES
|
|
|
814
994
|
$ qfg workspace bootstrap --dir ./our-config --skip-validate
|
|
815
995
|
```
|
|
816
996
|
|
|
817
|
-
_See code: [src/commands/workspace/bootstrap.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
997
|
+
_See code: [src/commands/workspace/bootstrap.ts](https://github.com/quonfig/cli/blob/v0.0.5/src/commands/workspace/bootstrap.ts)_
|
|
818
998
|
<!-- commandsstop -->
|
|
819
999
|
|
|
820
1000
|
## Local Development
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseCommand } from '../index.js';
|
|
2
|
+
import { JsonObj } from '../result.js';
|
|
3
|
+
export default class ConfigSchema extends BaseCommand {
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {
|
|
7
|
+
'json-schema': import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
8
|
+
};
|
|
9
|
+
run(): Promise<JsonObj | void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import { BaseCommand } from '../index.js';
|
|
3
|
+
import { storedConfigJsonSchema } from '../init/schema.js';
|
|
4
|
+
const REFERENCE = `
|
|
5
|
+
────────────────────────────────────────────────────────────
|
|
6
|
+
FILE LAYOUT
|
|
7
|
+
────────────────────────────────────────────────────────────
|
|
8
|
+
Config files live in your workspace (clone with: qfg pull --dir ./my-config):
|
|
9
|
+
|
|
10
|
+
feature-flags/ Boolean feature flags (on/off, targeting, percentage rollouts)
|
|
11
|
+
configs/ Typed config values (string, int, double, json, string-list)
|
|
12
|
+
segments/ User segments for targeting rules
|
|
13
|
+
log-levels/ Dynamic log-level configs
|
|
14
|
+
|
|
15
|
+
────────────────────────────────────────────────────────────
|
|
16
|
+
RULE EVALUATION
|
|
17
|
+
────────────────────────────────────────────────────────────
|
|
18
|
+
Rules are evaluated in ORDER — the FIRST matching rule wins.
|
|
19
|
+
Put specific rules (user lists, segments) BEFORE catch-all rules.
|
|
20
|
+
criteria: [] means "match everyone" (unconditional / catch-all)
|
|
21
|
+
criteria: [..] multiple entries in one rule are ANDed together
|
|
22
|
+
|
|
23
|
+
────────────────────────────────────────────────────────────
|
|
24
|
+
EXAMPLE: complex targeting + rollout in production
|
|
25
|
+
────────────────────────────────────────────────────────────
|
|
26
|
+
Four rules in order:
|
|
27
|
+
1. Always ON for users in an allowlist
|
|
28
|
+
2. Always ON for users in the "beta" segment
|
|
29
|
+
3. Always OFF for users in the "holdout" segment
|
|
30
|
+
4. 50/50 split for everyone else
|
|
31
|
+
|
|
32
|
+
{
|
|
33
|
+
"key": "my.feature.flag",
|
|
34
|
+
"type": "feature_flag",
|
|
35
|
+
"valueType": "bool",
|
|
36
|
+
"default": {
|
|
37
|
+
"rules": [{ "criteria": [], "value": { "type": "bool", "value": false } }]
|
|
38
|
+
},
|
|
39
|
+
"environments": [{
|
|
40
|
+
"id": "production",
|
|
41
|
+
"rules": [
|
|
42
|
+
{
|
|
43
|
+
"criteria": [{
|
|
44
|
+
"operator": "PROP_IS_ONE_OF",
|
|
45
|
+
"propertyName": "user.key",
|
|
46
|
+
"valueToMatch": { "type": "string_list", "value": ["user-123", "user-456"] }
|
|
47
|
+
}],
|
|
48
|
+
"value": { "type": "bool", "value": true }
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"criteria": [{
|
|
52
|
+
"operator": "IN_SEG",
|
|
53
|
+
"valueToMatch": { "type": "string", "value": "beta" }
|
|
54
|
+
}],
|
|
55
|
+
"value": { "type": "bool", "value": true }
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"criteria": [{
|
|
59
|
+
"operator": "IN_SEG",
|
|
60
|
+
"valueToMatch": { "type": "string", "value": "holdout" }
|
|
61
|
+
}],
|
|
62
|
+
"value": { "type": "bool", "value": false }
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"criteria": [],
|
|
66
|
+
"value": {
|
|
67
|
+
"type": "weighted_values",
|
|
68
|
+
"value": {
|
|
69
|
+
"hashByPropertyName": "user.key",
|
|
70
|
+
"weightedValues": [
|
|
71
|
+
{ "value": { "type": "bool", "value": true }, "weight": 50000 },
|
|
72
|
+
{ "value": { "type": "bool", "value": false }, "weight": 50000 }
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
}]
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
────────────────────────────────────────────────────────────
|
|
82
|
+
CRITERION FIELDS
|
|
83
|
+
────────────────────────────────────────────────────────────
|
|
84
|
+
Each criterion object has:
|
|
85
|
+
operator (required) — see operator table below
|
|
86
|
+
propertyName (required for PROP_* operators) — user property, e.g. "user.key", "user.plan"
|
|
87
|
+
valueToMatch (required for all except ALWAYS_TRUE) — typed value to compare against
|
|
88
|
+
|
|
89
|
+
────────────────────────────────────────────────────────────
|
|
90
|
+
OPERATOR REFERENCE
|
|
91
|
+
────────────────────────────────────────────────────────────
|
|
92
|
+
Operator valueToMatch type Notes
|
|
93
|
+
────────────────────────────────────────────────────────
|
|
94
|
+
ALWAYS_TRUE (none) Unconditional match; use for catch-all rules
|
|
95
|
+
PROP_IS_ONE_OF string_list propertyName value is in the list
|
|
96
|
+
PROP_IS_NOT_ONE_OF string_list propertyName value is NOT in the list
|
|
97
|
+
PROP_STARTS_WITH_ONE_OF string_list string prefix match
|
|
98
|
+
PROP_DOES_NOT_START_WITH_ONE_OF string_list
|
|
99
|
+
PROP_ENDS_WITH_ONE_OF string_list string suffix match
|
|
100
|
+
PROP_DOES_NOT_END_WITH_ONE_OF string_list
|
|
101
|
+
PROP_CONTAINS_ONE_OF string_list substring match
|
|
102
|
+
PROP_DOES_NOT_CONTAIN_ONE_OF string_list
|
|
103
|
+
PROP_LESS_THAN int or double numeric comparison
|
|
104
|
+
PROP_LESS_THAN_OR_EQUAL int or double
|
|
105
|
+
PROP_GREATER_THAN int or double
|
|
106
|
+
PROP_GREATER_THAN_OR_EQUAL int or double
|
|
107
|
+
PROP_BEFORE string (ISO 8601) date/time comparison
|
|
108
|
+
PROP_AFTER string (ISO 8601)
|
|
109
|
+
PROP_MATCHES string regex match
|
|
110
|
+
PROP_DOES_NOT_MATCH string
|
|
111
|
+
IN_SEG string value = segment key (no propertyName needed)
|
|
112
|
+
NOT_IN_SEG string value = segment key (no propertyName needed)
|
|
113
|
+
IN_INT_RANGE int_range value = {min, max}
|
|
114
|
+
LOOKUP_KEY_IN string_list matches if SDK lookup key is in the list
|
|
115
|
+
LOOKUP_KEY_NOT_IN string_list
|
|
116
|
+
|
|
117
|
+
valueToMatch format: { "type": "<type>", "value": <value> }
|
|
118
|
+
string_list → { "type": "string_list", "value": ["a", "b"] }
|
|
119
|
+
string → { "type": "string", "value": "beta" }
|
|
120
|
+
int → { "type": "int", "value": 42 }
|
|
121
|
+
double → { "type": "double", "value": 3.14 }
|
|
122
|
+
|
|
123
|
+
────────────────────────────────────────────────────────────
|
|
124
|
+
PERCENTAGE ROLLOUT (weighted_values)
|
|
125
|
+
────────────────────────────────────────────────────────────
|
|
126
|
+
Weights are integers out of 100,000 (not percentages):
|
|
127
|
+
5%=5000 10%=10000 20%=20000 50%=50000 100%=100000
|
|
128
|
+
All weights in one rule MUST sum to exactly 100,000.
|
|
129
|
+
|
|
130
|
+
hashByPropertyName controls the bucket assignment property (default: "user.key").
|
|
131
|
+
|
|
132
|
+
────────────────────────────────────────────────────────────
|
|
133
|
+
RELATED COMMANDS
|
|
134
|
+
────────────────────────────────────────────────────────────
|
|
135
|
+
qfg create my.flag --type boolean-flag create a new flag
|
|
136
|
+
qfg set-default my.flag --environment prod ... set a scalar fallback value
|
|
137
|
+
qfg set-rollout my.flag --environment prod ... set a simple percentage rollout
|
|
138
|
+
qfg pull --dir ./config clone workspace to edit JSON directly
|
|
139
|
+
qfg verify ./config validate all JSON files before pushing
|
|
140
|
+
qfg info my.flag inspect current values and rules
|
|
141
|
+
qfg config-schema --json-schema print the machine-readable JSON Schema
|
|
142
|
+
`.trim();
|
|
143
|
+
export default class ConfigSchema extends BaseCommand {
|
|
144
|
+
static description = 'Print the config file format reference: rules engine, operators, targeting criteria, segments, and weighted rollouts. ' +
|
|
145
|
+
'Use --json-schema for the machine-readable JSON Schema document.';
|
|
146
|
+
static examples = [
|
|
147
|
+
'<%= config.bin %> <%= command.id %> # human-readable operator reference + examples',
|
|
148
|
+
'<%= config.bin %> <%= command.id %> --json-schema # full JSON Schema document (copy into your editor)',
|
|
149
|
+
];
|
|
150
|
+
static flags = {
|
|
151
|
+
'json-schema': Flags.boolean({
|
|
152
|
+
default: false,
|
|
153
|
+
description: 'Output the full JSON Schema document for config files instead of the human-readable reference',
|
|
154
|
+
}),
|
|
155
|
+
};
|
|
156
|
+
async run() {
|
|
157
|
+
const { flags } = await this.parse(ConfigSchema);
|
|
158
|
+
if (flags['json-schema']) {
|
|
159
|
+
const schema = storedConfigJsonSchema();
|
|
160
|
+
this.log(JSON.stringify(schema, null, 2));
|
|
161
|
+
return schema;
|
|
162
|
+
}
|
|
163
|
+
this.log(REFERENCE);
|
|
164
|
+
}
|
|
165
|
+
}
|