@quonfig/cli 0.0.11 → 0.0.12

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 (44) hide show
  1. package/README.md +154 -28
  2. package/dist/commands/migrate/doctor.d.ts +12 -0
  3. package/dist/commands/migrate/doctor.js +63 -0
  4. package/dist/commands/migrate/status.d.ts +10 -0
  5. package/dist/commands/migrate/status.js +112 -0
  6. package/dist/commands/migrate.d.ts +20 -0
  7. package/dist/commands/migrate.js +256 -0
  8. package/dist/migrate/doctor.d.ts +27 -0
  9. package/dist/migrate/doctor.js +220 -0
  10. package/dist/migrate/identifier-map.d.ts +14 -0
  11. package/dist/migrate/identifier-map.js +55 -0
  12. package/dist/migrate/import-state.d.ts +14 -0
  13. package/dist/migrate/import-state.js +60 -0
  14. package/dist/migrate/migration-report.d.ts +42 -0
  15. package/dist/migrate/migration-report.js +93 -0
  16. package/dist/migrate/push-strategy.d.ts +34 -0
  17. package/dist/migrate/push-strategy.js +133 -0
  18. package/dist/migrate/push-to-cloud.d.ts +15 -0
  19. package/dist/migrate/push-to-cloud.js +31 -0
  20. package/dist/migrate/registry.d.ts +6 -0
  21. package/dist/migrate/registry.js +25 -0
  22. package/dist/migrate/source.d.ts +22 -0
  23. package/dist/migrate/source.js +12 -0
  24. package/dist/migrate/sources/flagsmith.d.ts +2 -0
  25. package/dist/migrate/sources/flagsmith.js +18 -0
  26. package/dist/migrate/sources/launch/api.d.ts +7 -0
  27. package/dist/migrate/sources/launch/api.js +75 -0
  28. package/dist/migrate/sources/launch/translate.d.ts +6 -0
  29. package/dist/migrate/sources/launch/translate.js +190 -0
  30. package/dist/migrate/sources/launch/types.d.ts +68 -0
  31. package/dist/migrate/sources/launch/types.js +1 -0
  32. package/dist/migrate/sources/launch.d.ts +3 -0
  33. package/dist/migrate/sources/launch.js +70 -0
  34. package/dist/migrate/sources/launchdarkly.d.ts +2 -0
  35. package/dist/migrate/sources/launchdarkly.js +18 -0
  36. package/dist/ui/get-confirmation.d.ts +2 -1
  37. package/dist/ui/get-confirmation.js +9 -1
  38. package/dist/ui/get-value.d.ts +1 -1
  39. package/dist/ui/get-value.js +3 -2
  40. package/dist/util/is-interactive.d.ts +21 -1
  41. package/dist/util/is-interactive.js +21 -1
  42. package/dist/verify/validate.js +6 -1
  43. package/oclif.manifest.json +287 -1
  44. 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.11 linux-x64 node-v24.4.1
17
+ @quonfig/cli/0.0.12 linux-x64 node-v24.4.1
18
18
  $ qfg --help [COMMAND]
19
19
  USAGE
20
20
  $ qfg COMMAND
@@ -40,6 +40,9 @@ USAGE
40
40
  * [`qfg login`](#qfg-login)
41
41
  * [`qfg logout`](#qfg-logout)
42
42
  * [`qfg mcp`](#qfg-mcp)
43
+ * [`qfg migrate`](#qfg-migrate)
44
+ * [`qfg migrate doctor`](#qfg-migrate-doctor)
45
+ * [`qfg migrate status`](#qfg-migrate-status)
43
46
  * [`qfg override [NAME]`](#qfg-override-name)
44
47
  * [`qfg pull`](#qfg-pull)
45
48
  * [`qfg schema NAME`](#qfg-schema-name)
@@ -84,7 +87,7 @@ EXAMPLES
84
87
  $ qfg config-schema --json-schema # full JSON Schema document (copy into your editor)
85
88
  ```
86
89
 
87
- _See code: [src/commands/config-schema.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/config-schema.ts)_
90
+ _See code: [src/commands/config-schema.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/config-schema.ts)_
88
91
 
89
92
  ## `qfg create NAME`
90
93
 
@@ -156,7 +159,7 @@ EXAMPLES
156
159
  $ qfg set-rollout my.new.flag --environment production --true-percent 20
157
160
  ```
158
161
 
159
- _See code: [src/commands/create.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/create.ts)_
162
+ _See code: [src/commands/create.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/create.ts)_
160
163
 
161
164
  ## `qfg flag info [NAME]`
162
165
 
@@ -356,7 +359,7 @@ EXAMPLES
356
359
  $ qfg generate --targets node-ts -o ./dist # combine with targets
357
360
  ```
358
361
 
359
- _See code: [src/commands/generate.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/generate.ts)_
362
+ _See code: [src/commands/generate.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/generate.ts)_
360
363
 
361
364
  ## `qfg generate-new-hex-key`
362
365
 
@@ -379,7 +382,7 @@ EXAMPLES
379
382
  $ qfg generate-new-hex-key
380
383
  ```
381
384
 
382
- _See code: [src/commands/generate-new-hex-key.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/generate-new-hex-key.ts)_
385
+ _See code: [src/commands/generate-new-hex-key.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/generate-new-hex-key.ts)_
383
386
 
384
387
  ## `qfg get [NAME]`
385
388
 
@@ -411,7 +414,7 @@ EXAMPLES
411
414
  $ qfg get my.config.name --environment=production
412
415
  ```
413
416
 
414
- _See code: [src/commands/get.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/get.ts)_
417
+ _See code: [src/commands/get.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/get.ts)_
415
418
 
416
419
  ## `qfg info [NAME]`
417
420
 
@@ -459,7 +462,7 @@ EXAMPLES
459
462
  $ qfg info my.config.name --exclude-evaluations # skip 24h stats
460
463
  ```
461
464
 
462
- _See code: [src/commands/info.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/info.ts)_
465
+ _See code: [src/commands/info.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/info.ts)_
463
466
 
464
467
  ## `qfg init [DIRECTORY]`
465
468
 
@@ -497,7 +500,7 @@ EXAMPLES
497
500
  $ qfg init --dry-run
498
501
  ```
499
502
 
500
- _See code: [src/commands/init.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/init.ts)_
503
+ _See code: [src/commands/init.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/init.ts)_
501
504
 
502
505
  ## `qfg interactive`
503
506
 
@@ -515,7 +518,7 @@ EXAMPLES
515
518
  $ qfg
516
519
  ```
517
520
 
518
- _See code: [src/commands/interactive.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/interactive.ts)_
521
+ _See code: [src/commands/interactive.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/interactive.ts)_
519
522
 
520
523
  ## `qfg list`
521
524
 
@@ -555,7 +558,7 @@ EXAMPLES
555
558
  $ qfg list --feature-flags
556
559
  ```
557
560
 
558
- _See code: [src/commands/list.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/list.ts)_
561
+ _See code: [src/commands/list.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/list.ts)_
559
562
 
560
563
  ## `qfg login`
561
564
 
@@ -580,7 +583,7 @@ EXAMPLES
580
583
  $ qfg login --profile myprofile
581
584
  ```
582
585
 
583
- _See code: [src/commands/login.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/login.ts)_
586
+ _See code: [src/commands/login.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/login.ts)_
584
587
 
585
588
  ## `qfg logout`
586
589
 
@@ -603,7 +606,7 @@ EXAMPLES
603
606
  $ qfg logout
604
607
  ```
605
608
 
606
- _See code: [src/commands/logout.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/logout.ts)_
609
+ _See code: [src/commands/logout.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/logout.ts)_
607
610
 
608
611
  ## `qfg mcp`
609
612
 
@@ -636,7 +639,130 @@ EXAMPLES
636
639
  $ qfg mcp --url http://local-app.quonfig-staging.com:3003/api/v1/mcp
637
640
  ```
638
641
 
639
- _See code: [src/commands/mcp.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/mcp.ts)_
642
+ _See code: [src/commands/mcp.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/mcp.ts)_
643
+
644
+ ## `qfg migrate`
645
+
646
+ Migrate flags and configs from a legacy feature-flag system into a Quonfig workspace.
647
+
648
+ ```
649
+ USAGE
650
+ $ qfg migrate --from launch|launchdarkly|flagsmith [--json] [--interactive] [--no-color] [--verbose]
651
+ [--api-key <value>] [--dir <value>] [--dry-run] [--push] [--recent <value>] [--reset] [--since <value>] [--staging]
652
+ [--workspace <value>]
653
+
654
+ FLAGS
655
+ --api-key=<value> API key for the legacy source (or set LAUNCH_API_KEY)
656
+ --dir=<value> Target local workspace directory. Defaults to cwd if it looks like a Quonfig workspace, otherwise
657
+ ./quonfig-config.
658
+ --dry-run Fetch and summarize changes without writing anything
659
+ --from=<option> (required) Legacy source to migrate from
660
+ <options: launch|launchdarkly|flagsmith>
661
+ --push After migrating to a local dir, also push to the given --workspace on Quonfig cloud
662
+ --recent=<value> Import only the last N changes (useful for tire-kicking)
663
+ --reset Ignore the delta cursor and re-import everything from scratch
664
+ --since=<value> Override the delta cursor (epoch milliseconds or ISO-8601 timestamp)
665
+ --staging Hit the staging API for the source (dev-only)
666
+ --workspace=<value> Quonfig cloud workspace slug to push to. Requires `qfg login` and is typically combined with
667
+ --push.
668
+
669
+ GLOBAL FLAGS
670
+ --[no-]interactive Force interactive mode
671
+ --json Format output as json.
672
+ --no-color Do not colorize output
673
+ --verbose Verbose output
674
+
675
+ DESCRIPTION
676
+ Migrate flags and configs from a legacy feature-flag system into a Quonfig workspace.
677
+
678
+ Currently supported sources:
679
+ launch — Reforge Launch (ported from launch-migrator)
680
+
681
+ See https://docs.quonfig.com/docs/migrating/from-launch for the step-by-step guide,
682
+ and https://docs.quonfig.com/docs/migrating/troubleshooting when something goes sideways.
683
+
684
+ EXAMPLES
685
+ $ qfg migrate --from launch --api-key $LAUNCH_API_KEY --dir ./quonfig-config
686
+
687
+ $ qfg migrate --from launch --api-key $LAUNCH_API_KEY --workspace acme-prod --push
688
+
689
+ $ qfg migrate --from launch --api-key $LAUNCH_API_KEY --dir ./quonfig-config --reset
690
+
691
+ $ qfg migrate --from launch --api-key $LAUNCH_API_KEY --dir ./quonfig-config --dry-run
692
+
693
+ $ qfg migrate --from launch --api-key $LAUNCH_API_KEY --dir ./quonfig-config --staging
694
+ ```
695
+
696
+ _See code: [src/commands/migrate.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/migrate.ts)_
697
+
698
+ ## `qfg migrate doctor`
699
+
700
+ Preflight health checks for `qfg migrate`. Verifies auth, workspace provisioning, working tree, and identifier collisions.
701
+
702
+ ```
703
+ USAGE
704
+ $ qfg migrate doctor [--json] [--interactive] [--no-color] [--verbose] [--api-key <value>] [--dir <value>] [--from
705
+ launch] [--language <value>]
706
+
707
+ FLAGS
708
+ --api-key=<value> Legacy SDK API key to validate against the source
709
+ --dir=<value> [default: .] Workspace directory to check (git clean / identifier map)
710
+ --from=<option> [default: launch] Legacy SDK to migrate from
711
+ <options: launch>
712
+ --language=<value> Customer SDK language — used to warn when datadir mode is unavailable (e.g. javascript-browser)
713
+
714
+ GLOBAL FLAGS
715
+ --[no-]interactive Force interactive mode
716
+ --json Format output as json.
717
+ --no-color Do not colorize output
718
+ --verbose Verbose output
719
+
720
+ DESCRIPTION
721
+ Preflight health checks for `qfg migrate`. Verifies auth, workspace provisioning, working tree, and identifier
722
+ collisions.
723
+
724
+ EXAMPLES
725
+ $ qfg migrate doctor
726
+
727
+ $ qfg migrate doctor --from launch --api-key $LAUNCH_API_KEY
728
+
729
+ $ qfg migrate doctor --dir ./my-workspace --language node
730
+
731
+ $ qfg migrate doctor --json
732
+ ```
733
+
734
+ _See code: [src/commands/migrate/doctor.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/migrate/doctor.ts)_
735
+
736
+ ## `qfg migrate status`
737
+
738
+ Show the status of a workspace migrated with `qfg migrate`. Reads .qf/import-state.json and summarizes source, counts, and next steps.
739
+
740
+ ```
741
+ USAGE
742
+ $ qfg migrate status [--json] [--interactive] [--no-color] [--verbose] [--dir <value>]
743
+
744
+ FLAGS
745
+ --dir=<value> [default: .] Workspace directory to inspect
746
+
747
+ GLOBAL FLAGS
748
+ --[no-]interactive Force interactive mode
749
+ --json Format output as json.
750
+ --no-color Do not colorize output
751
+ --verbose Verbose output
752
+
753
+ DESCRIPTION
754
+ Show the status of a workspace migrated with `qfg migrate`. Reads .qf/import-state.json and summarizes source, counts,
755
+ and next steps.
756
+
757
+ EXAMPLES
758
+ $ qfg migrate status
759
+
760
+ $ qfg migrate status --dir ./my-workspace
761
+
762
+ $ qfg migrate status --json
763
+ ```
764
+
765
+ _See code: [src/commands/migrate/status.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/migrate/status.ts)_
640
766
 
641
767
  ## `qfg override [NAME]`
642
768
 
@@ -675,7 +801,7 @@ EXAMPLES
675
801
  $ qfg override my.double.config --value=3.14159
676
802
  ```
677
803
 
678
- _See code: [src/commands/override.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/override.ts)_
804
+ _See code: [src/commands/override.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/override.ts)_
679
805
 
680
806
  ## `qfg pull`
681
807
 
@@ -719,7 +845,7 @@ EXAMPLES
719
845
  $ qfg pull # uses QUONFIG_DIR env var
720
846
  ```
721
847
 
722
- _See code: [src/commands/pull.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/pull.ts)_
848
+ _See code: [src/commands/pull.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/pull.ts)_
723
849
 
724
850
  ## `qfg schema NAME`
725
851
 
@@ -757,7 +883,7 @@ EXAMPLES
757
883
  $ qfg schema my-schema --set-json-schema=@schemas/my-schema.json --protected
758
884
  ```
759
885
 
760
- _See code: [src/commands/schema.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/schema.ts)_
886
+ _See code: [src/commands/schema.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/schema.ts)_
761
887
 
762
888
  ## `qfg sdk-key`
763
889
 
@@ -784,7 +910,7 @@ EXAMPLES
784
910
  $ qfg sdk-key revoke <key-id>
785
911
  ```
786
912
 
787
- _See code: [src/commands/sdk-key.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/sdk-key.ts)_
913
+ _See code: [src/commands/sdk-key.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/sdk-key.ts)_
788
914
 
789
915
  ## `qfg sdk-key create`
790
916
 
@@ -816,7 +942,7 @@ EXAMPLES
816
942
  $ qfg sdk-key create --environment staging --type browser
817
943
  ```
818
944
 
819
- _See code: [src/commands/sdk-key/create.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/sdk-key/create.ts)_
945
+ _See code: [src/commands/sdk-key/create.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/sdk-key/create.ts)_
820
946
 
821
947
  ## `qfg sdk-key list`
822
948
 
@@ -845,7 +971,7 @@ EXAMPLES
845
971
  $ qfg sdk-key list --environment production
846
972
  ```
847
973
 
848
- _See code: [src/commands/sdk-key/list.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/sdk-key/list.ts)_
974
+ _See code: [src/commands/sdk-key/list.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/sdk-key/list.ts)_
849
975
 
850
976
  ## `qfg sdk-key revoke KEYID`
851
977
 
@@ -872,7 +998,7 @@ EXAMPLES
872
998
  $ qfg sdk-key revoke a1b2c3d4-e5f6-7890-abcd-ef1234567890
873
999
  ```
874
1000
 
875
- _See code: [src/commands/sdk-key/revoke.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/sdk-key/revoke.ts)_
1001
+ _See code: [src/commands/sdk-key/revoke.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/sdk-key/revoke.ts)_
876
1002
 
877
1003
  ## `qfg set-default [NAME]`
878
1004
 
@@ -939,7 +1065,7 @@ EXAMPLES
939
1065
  $ qfg set-rollout my.flag.name --environment production --true-percent 20
940
1066
  ```
941
1067
 
942
- _See code: [src/commands/set-default.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/set-default.ts)_
1068
+ _See code: [src/commands/set-default.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/set-default.ts)_
943
1069
 
944
1070
  ## `qfg set-rollout [NAME]`
945
1071
 
@@ -1016,7 +1142,7 @@ EXAMPLES
1016
1142
  $ qfg set-rollout my.variant.flag --environment production --weights "a:33,b:33,c:34" --hash-by user.id
1017
1143
  ```
1018
1144
 
1019
- _See code: [src/commands/set-rollout.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/set-rollout.ts)_
1145
+ _See code: [src/commands/set-rollout.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/set-rollout.ts)_
1020
1146
 
1021
1147
  ## `qfg sync`
1022
1148
 
@@ -1048,7 +1174,7 @@ EXAMPLES
1048
1174
  $ qfg sync --watch --dir ./our-config --interval 30
1049
1175
  ```
1050
1176
 
1051
- _See code: [src/commands/sync.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/sync.ts)_
1177
+ _See code: [src/commands/sync.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/sync.ts)_
1052
1178
 
1053
1179
  ## `qfg toggle [NAME]`
1054
1180
 
@@ -1146,7 +1272,7 @@ EXAMPLES
1146
1272
  $ qfg verify --json
1147
1273
  ```
1148
1274
 
1149
- _See code: [src/commands/verify.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/verify.ts)_
1275
+ _See code: [src/commands/verify.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/verify.ts)_
1150
1276
 
1151
1277
  ## `qfg whoami`
1152
1278
 
@@ -1169,7 +1295,7 @@ EXAMPLES
1169
1295
  $ qfg whoami
1170
1296
  ```
1171
1297
 
1172
- _See code: [src/commands/whoami.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/whoami.ts)_
1298
+ _See code: [src/commands/whoami.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/whoami.ts)_
1173
1299
 
1174
1300
  ## `qfg workspace`
1175
1301
 
@@ -1192,7 +1318,7 @@ EXAMPLES
1192
1318
  $ qfg workspace
1193
1319
  ```
1194
1320
 
1195
- _See code: [src/commands/workspace.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/workspace.ts)_
1321
+ _See code: [src/commands/workspace.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/workspace.ts)_
1196
1322
 
1197
1323
  ## `qfg workspace bootstrap`
1198
1324
 
@@ -1225,7 +1351,7 @@ EXAMPLES
1225
1351
  $ qfg workspace bootstrap --dir ./our-config --skip-validate
1226
1352
  ```
1227
1353
 
1228
- _See code: [src/commands/workspace/bootstrap.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/workspace/bootstrap.ts)_
1354
+ _See code: [src/commands/workspace/bootstrap.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/workspace/bootstrap.ts)_
1229
1355
 
1230
1356
  ## `qfg workspace switch`
1231
1357
 
@@ -1248,7 +1374,7 @@ EXAMPLES
1248
1374
  $ qfg workspace switch
1249
1375
  ```
1250
1376
 
1251
- _See code: [src/commands/workspace/switch.ts](https://github.com/quonfig/cli/blob/v0.0.11/src/commands/workspace/switch.ts)_
1377
+ _See code: [src/commands/workspace/switch.ts](https://github.com/quonfig/cli/blob/v0.0.12/src/commands/workspace/switch.ts)_
1252
1378
  <!-- commandsstop -->
1253
1379
 
1254
1380
  ## Local Development
@@ -0,0 +1,12 @@
1
+ import { BaseCommand } from '../../index.js';
2
+ export default class MigrateDoctor extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ 'api-key': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
7
+ dir: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
8
+ from: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
9
+ language: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
@@ -0,0 +1,63 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { BaseCommand } from '../../index.js';
3
+ import { formatHumanReport, runDoctor, } from '../../migrate/doctor.js';
4
+ import { loadTokens } from '../../util/token-storage.js';
5
+ const SUPPORTED_SOURCES = new Set(['launch']);
6
+ const defaultLoadSession = async () => {
7
+ const tokens = await loadTokens();
8
+ if (!tokens?.accessToken)
9
+ return null;
10
+ return { expiresAt: tokens.expiresAt ?? 0 };
11
+ };
12
+ export default class MigrateDoctor extends BaseCommand {
13
+ static description = 'Preflight health checks for `qfg migrate`. Verifies auth, workspace provisioning, working tree, and identifier collisions.';
14
+ static examples = [
15
+ '<%= config.bin %> <%= command.id %>',
16
+ '<%= config.bin %> <%= command.id %> --from launch --api-key $LAUNCH_API_KEY',
17
+ '<%= config.bin %> <%= command.id %> --dir ./my-workspace --language node',
18
+ '<%= config.bin %> <%= command.id %> --json',
19
+ ];
20
+ static flags = {
21
+ 'api-key': Flags.string({
22
+ description: 'Legacy SDK API key to validate against the source',
23
+ required: false,
24
+ }),
25
+ dir: Flags.string({
26
+ default: '.',
27
+ description: 'Workspace directory to check (git clean / identifier map)',
28
+ }),
29
+ from: Flags.string({
30
+ default: 'launch',
31
+ description: 'Legacy SDK to migrate from',
32
+ options: ['launch'],
33
+ }),
34
+ language: Flags.string({
35
+ description: 'Customer SDK language — used to warn when datadir mode is unavailable (e.g. javascript-browser)',
36
+ required: false,
37
+ }),
38
+ };
39
+ async run() {
40
+ const { flags } = await this.parse(MigrateDoctor);
41
+ if (!SUPPORTED_SOURCES.has(flags.from)) {
42
+ this.err(`Unsupported --from source: ${flags.from}. Only 'launch' is supported today.`);
43
+ return;
44
+ }
45
+ const ctx = {
46
+ apiKey: flags['api-key'],
47
+ dir: flags.dir,
48
+ from: flags.from,
49
+ language: flags.language,
50
+ loadSession: defaultLoadSession,
51
+ };
52
+ const report = await runDoctor(ctx);
53
+ if (this.jsonEnabled()) {
54
+ process.stdout.write(JSON.stringify(report) + '\n');
55
+ }
56
+ else {
57
+ this.log(formatHumanReport(report));
58
+ }
59
+ if (!report.passed) {
60
+ this.exit(1);
61
+ }
62
+ }
63
+ }
@@ -0,0 +1,10 @@
1
+ import type { JsonObj } from '../../result.js';
2
+ import { BaseCommand } from '../../index.js';
3
+ export default class MigrateStatus extends BaseCommand {
4
+ static description: string;
5
+ static examples: string[];
6
+ static flags: {
7
+ dir: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
8
+ };
9
+ run(): Promise<JsonObj | void>;
10
+ }
@@ -0,0 +1,112 @@
1
+ import { Flags } from '@oclif/core';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { BaseCommand } from '../../index.js';
5
+ import { readImportState } from '../../migrate/import-state.js';
6
+ const FLAGS_DIR = 'feature-flags';
7
+ const SEGMENTS_DIR = 'segments';
8
+ const WORKSPACE_FILE = 'quonfig.json';
9
+ const NO_STATE_MESSAGE = 'No migration state found. Run qfg migrate --from <source> first.';
10
+ function countJsonFiles(dir) {
11
+ if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory())
12
+ return 0;
13
+ return fs
14
+ .readdirSync(dir)
15
+ .filter((name) => name.endsWith('.json') && !name.startsWith('.'))
16
+ .length;
17
+ }
18
+ function countEnvironments(dir) {
19
+ const file = path.join(dir, WORKSPACE_FILE);
20
+ if (!fs.existsSync(file))
21
+ return 0;
22
+ try {
23
+ const parsed = JSON.parse(fs.readFileSync(file, 'utf8'));
24
+ return Array.isArray(parsed.environments) ? parsed.environments.length : 0;
25
+ }
26
+ catch {
27
+ return 0;
28
+ }
29
+ }
30
+ function workspaceCounts(dir) {
31
+ return {
32
+ environments: countEnvironments(dir),
33
+ flags: countJsonFiles(path.join(dir, FLAGS_DIR)),
34
+ segments: countJsonFiles(path.join(dir, SEGMENTS_DIR)),
35
+ };
36
+ }
37
+ function toIsoTimestamp(value) {
38
+ if (value == null)
39
+ return null;
40
+ const date = typeof value === 'number' ? new Date(value) : new Date(value);
41
+ if (Number.isNaN(date.getTime()))
42
+ return null;
43
+ return date.toISOString();
44
+ }
45
+ function nextHint(source, counts) {
46
+ if (counts.flags === 0 && counts.segments === 0) {
47
+ return `Run \`qfg migrate --from ${source}\` to import flags and segments.`;
48
+ }
49
+ return `Run \`qfg migrate my-code --from ${source}\` to update your SDK call sites, or re-run \`qfg migrate --from ${source}\` to pick up changes.`;
50
+ }
51
+ function formatHuman(payload) {
52
+ const lines = [];
53
+ lines.push(`Source: ${payload.source}`);
54
+ lines.push(`Source workspace: ${payload.sourceWorkspaceId ?? '(not recorded)'}`);
55
+ lines.push(`Last processed at: ${payload.lastProcessedAtIso ?? '(not recorded)'}`);
56
+ lines.push(`Workspace dir: ${payload.dir}`);
57
+ lines.push('');
58
+ lines.push('Counts:');
59
+ lines.push(` Flags: ${payload.counts.flags}`);
60
+ lines.push(` Segments: ${payload.counts.segments}`);
61
+ lines.push(` Environments: ${payload.counts.environments}`);
62
+ lines.push('');
63
+ lines.push(`Next: ${payload.next}`);
64
+ return lines.join('\n');
65
+ }
66
+ export default class MigrateStatus extends BaseCommand {
67
+ static description = 'Show the status of a workspace migrated with `qfg migrate`. Reads .qf/import-state.json and summarizes source, counts, and next steps.';
68
+ static examples = [
69
+ '<%= config.bin %> <%= command.id %>',
70
+ '<%= config.bin %> <%= command.id %> --dir ./my-workspace',
71
+ '<%= config.bin %> <%= command.id %> --json',
72
+ ];
73
+ static flags = {
74
+ dir: Flags.string({
75
+ default: '.',
76
+ description: 'Workspace directory to inspect',
77
+ }),
78
+ };
79
+ async run() {
80
+ const { flags } = await this.parse(MigrateStatus);
81
+ const dir = path.resolve(flags.dir);
82
+ const state = readImportState(dir);
83
+ if (!state) {
84
+ const payload = {
85
+ dir,
86
+ found: false,
87
+ message: NO_STATE_MESSAGE,
88
+ };
89
+ if (this.jsonEnabled())
90
+ return payload;
91
+ this.log(NO_STATE_MESSAGE);
92
+ return payload;
93
+ }
94
+ const counts = workspaceCounts(dir);
95
+ const lastProcessedAtIso = toIsoTimestamp(state.lastProcessedAt);
96
+ const next = nextHint(state.source, counts);
97
+ const payload = {
98
+ counts,
99
+ dir,
100
+ found: true,
101
+ lastProcessedAt: state.lastProcessedAt ?? null,
102
+ lastProcessedAtIso,
103
+ next,
104
+ source: state.source,
105
+ sourceWorkspaceId: state.sourceWorkspaceId ?? null,
106
+ };
107
+ if (this.jsonEnabled())
108
+ return payload;
109
+ this.log(formatHuman(payload));
110
+ return payload;
111
+ }
112
+ }
@@ -0,0 +1,20 @@
1
+ import type { JsonObj } from '../result.js';
2
+ import { BaseCommand } from '../index.js';
3
+ export default class Migrate extends BaseCommand {
4
+ static description: string;
5
+ static examples: string[];
6
+ static flags: {
7
+ 'api-key': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
8
+ dir: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
9
+ 'dry-run': import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
10
+ from: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
11
+ push: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
12
+ recent: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
13
+ reset: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
14
+ since: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
15
+ staging: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
16
+ workspace: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
17
+ };
18
+ run(): Promise<JsonObj | void>;
19
+ private resolvePushWorkspace;
20
+ }