@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 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.4 linux-x64 node-v24.4.1
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 item in Quonfig
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 item in Quonfig
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.4/src/commands/create.ts)_
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.4/src/commands/download.ts)_
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.4/src/commands/generate.ts)_
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.4/src/commands/generate-new-hex-key.ts)_
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.4/src/commands/get.ts)_
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 details about the provided config/feature-flag/etc.
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 details about the provided config/feature-flag/etc.
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.4/src/commands/info.ts)_
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.4/src/commands/init.ts)_
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.4/src/commands/interactive.ts)_
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.4/src/commands/list.ts)_
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.4/src/commands/login.ts)_
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.4/src/commands/logout.ts)_
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.4/src/commands/mcp.ts)_
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.4/src/commands/override.ts)_
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.4/src/commands/profile.ts)_
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 directory from the workspace Gitea repo
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 directory from the workspace Gitea repo
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.4/src/commands/pull.ts)_
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.4/src/commands/schema.ts)_
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.4/src/commands/serve.ts)_
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/update the default value for an environment (other rules still apply)
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/update the default value for an environment (other rules still apply)
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 # will prompt for value and env
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-default.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/set-default.ts)_
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.4/src/commands/sync.ts)_
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.4/src/commands/verify.ts)_
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.4/src/commands/whoami.ts)_
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.4/src/commands/workspace.ts)_
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.4/src/commands/workspace/bootstrap.ts)_
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
+ }