@quonfig/cli 0.0.45 → 0.0.47

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
@@ -17,7 +17,7 @@ $ npm install -g @quonfig/cli
17
17
  $ qfg COMMAND
18
18
  running command...
19
19
  $ qfg (--version)
20
- @quonfig/cli/0.0.45 linux-x64 node-v24.4.1
20
+ @quonfig/cli/0.0.47 linux-x64 node-v24.4.1
21
21
  $ qfg --help [COMMAND]
22
22
  USAGE
23
23
  $ qfg COMMAND
@@ -195,7 +195,7 @@ EXAMPLES
195
195
  $ qfg activity restore my.flag --yes
196
196
  ```
197
197
 
198
- _See code: [src/commands/activity.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/activity.ts)_
198
+ _See code: [src/commands/activity.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/activity.ts)_
199
199
 
200
200
  ## `qfg activity deleted`
201
201
 
@@ -224,7 +224,7 @@ EXAMPLES
224
224
  $ qfg activity deleted --json
225
225
  ```
226
226
 
227
- _See code: [src/commands/activity/deleted.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/activity/deleted.ts)_
227
+ _See code: [src/commands/activity/deleted.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/activity/deleted.ts)_
228
228
 
229
229
  ## `qfg activity feed`
230
230
 
@@ -259,7 +259,7 @@ EXAMPLES
259
259
  $ qfg activity feed --json
260
260
  ```
261
261
 
262
- _See code: [src/commands/activity/feed.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/activity/feed.ts)_
262
+ _See code: [src/commands/activity/feed.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/activity/feed.ts)_
263
263
 
264
264
  ## `qfg activity history [NAME]`
265
265
 
@@ -293,7 +293,7 @@ EXAMPLES
293
293
  $ qfg activity history request.timeout --json
294
294
  ```
295
295
 
296
- _See code: [src/commands/activity/history.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/activity/history.ts)_
296
+ _See code: [src/commands/activity/history.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/activity/history.ts)_
297
297
 
298
298
  ## `qfg activity restore [NAME]`
299
299
 
@@ -332,7 +332,7 @@ EXAMPLES
332
332
  $ qfg activity restore request.timeout --type config --yes
333
333
  ```
334
334
 
335
- _See code: [src/commands/activity/restore.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/activity/restore.ts)_
335
+ _See code: [src/commands/activity/restore.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/activity/restore.ts)_
336
336
 
337
337
  ## `qfg audit-log [NAME]`
338
338
 
@@ -360,7 +360,7 @@ EXAMPLES
360
360
  $ qfg audit-log my.flag
361
361
  ```
362
362
 
363
- _See code: [src/commands/audit-log.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/audit-log.ts)_
363
+ _See code: [src/commands/audit-log.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/audit-log.ts)_
364
364
 
365
365
  ## `qfg config-schema`
366
366
 
@@ -389,7 +389,7 @@ EXAMPLES
389
389
  $ qfg config-schema --json-schema # full JSON Schema document (copy into your editor)
390
390
  ```
391
391
 
392
- _See code: [src/commands/config-schema.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/config-schema.ts)_
392
+ _See code: [src/commands/config-schema.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/config-schema.ts)_
393
393
 
394
394
  ## `qfg create NAME`
395
395
 
@@ -474,7 +474,7 @@ EXAMPLES
474
474
  $ qfg set-rollout my.new.flag --environment production --true-percent 20
475
475
  ```
476
476
 
477
- _See code: [src/commands/create.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/create.ts)_
477
+ _See code: [src/commands/create.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/create.ts)_
478
478
 
479
479
  ## `qfg delete NAME`
480
480
 
@@ -520,7 +520,7 @@ EXAMPLES
520
520
  $ qfg delete my.config --yes
521
521
  ```
522
522
 
523
- _See code: [src/commands/delete.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/delete.ts)_
523
+ _See code: [src/commands/delete.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/delete.ts)_
524
524
 
525
525
  ## `qfg flag info [NAME]`
526
526
 
@@ -723,7 +723,7 @@ EXAMPLES
723
723
  $ qfg generate --targets node-ts -o ./dist # combine with targets
724
724
  ```
725
725
 
726
- _See code: [src/commands/generate.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/generate.ts)_
726
+ _See code: [src/commands/generate.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/generate.ts)_
727
727
 
728
728
  ## `qfg generate-new-hex-key`
729
729
 
@@ -746,7 +746,7 @@ EXAMPLES
746
746
  $ qfg generate-new-hex-key
747
747
  ```
748
748
 
749
- _See code: [src/commands/generate-new-hex-key.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/generate-new-hex-key.ts)_
749
+ _See code: [src/commands/generate-new-hex-key.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/generate-new-hex-key.ts)_
750
750
 
751
751
  ## `qfg get [NAME]`
752
752
 
@@ -778,7 +778,7 @@ EXAMPLES
778
778
  $ qfg get my.config.name --environment=production
779
779
  ```
780
780
 
781
- _See code: [src/commands/get.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/get.ts)_
781
+ _See code: [src/commands/get.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/get.ts)_
782
782
 
783
783
  ## `qfg history NAME`
784
784
 
@@ -804,7 +804,7 @@ EXAMPLES
804
804
  $ qfg history my.flag
805
805
  ```
806
806
 
807
- _See code: [src/commands/history.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/history.ts)_
807
+ _See code: [src/commands/history.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/history.ts)_
808
808
 
809
809
  ## `qfg info [NAME]`
810
810
 
@@ -852,7 +852,7 @@ EXAMPLES
852
852
  $ qfg info my.config.name --exclude-evaluations # skip 24h stats
853
853
  ```
854
854
 
855
- _See code: [src/commands/info.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/info.ts)_
855
+ _See code: [src/commands/info.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/info.ts)_
856
856
 
857
857
  ## `qfg init [DIRECTORY]`
858
858
 
@@ -892,7 +892,7 @@ EXAMPLES
892
892
  $ qfg init --dry-run
893
893
  ```
894
894
 
895
- _See code: [src/commands/init.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/init.ts)_
895
+ _See code: [src/commands/init.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/init.ts)_
896
896
 
897
897
  ## `qfg interactive`
898
898
 
@@ -922,7 +922,7 @@ EXAMPLES
922
922
  $ qfg
923
923
  ```
924
924
 
925
- _See code: [src/commands/interactive.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/interactive.ts)_
925
+ _See code: [src/commands/interactive.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/interactive.ts)_
926
926
 
927
927
  ## `qfg list`
928
928
 
@@ -962,7 +962,7 @@ EXAMPLES
962
962
  $ qfg list --feature-flags
963
963
  ```
964
964
 
965
- _See code: [src/commands/list.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/list.ts)_
965
+ _See code: [src/commands/list.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/list.ts)_
966
966
 
967
967
  ## `qfg log`
968
968
 
@@ -987,7 +987,7 @@ EXAMPLES
987
987
  $ qfg log --limit 5
988
988
  ```
989
989
 
990
- _See code: [src/commands/log.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/log.ts)_
990
+ _See code: [src/commands/log.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/log.ts)_
991
991
 
992
992
  ## `qfg log-level NAME`
993
993
 
@@ -1052,7 +1052,7 @@ EXAMPLES
1052
1052
  $ qfg log-level log-level.my-app --target=Chatty --value=INFO --environment=production
1053
1053
  ```
1054
1054
 
1055
- _See code: [src/commands/log-level.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/log-level.ts)_
1055
+ _See code: [src/commands/log-level.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/log-level.ts)_
1056
1056
 
1057
1057
  ## `qfg login`
1058
1058
 
@@ -1077,7 +1077,7 @@ EXAMPLES
1077
1077
  $ qfg login --profile myprofile
1078
1078
  ```
1079
1079
 
1080
- _See code: [src/commands/login.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/login.ts)_
1080
+ _See code: [src/commands/login.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/login.ts)_
1081
1081
 
1082
1082
  ## `qfg logout`
1083
1083
 
@@ -1100,7 +1100,7 @@ EXAMPLES
1100
1100
  $ qfg logout
1101
1101
  ```
1102
1102
 
1103
- _See code: [src/commands/logout.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/logout.ts)_
1103
+ _See code: [src/commands/logout.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/logout.ts)_
1104
1104
 
1105
1105
  ## `qfg migrate`
1106
1106
 
@@ -1109,8 +1109,8 @@ Migrate flags and configs from a legacy feature-flag system into a Quonfig works
1109
1109
  ```
1110
1110
  USAGE
1111
1111
  $ qfg migrate --from launch|launchdarkly|flagsmith [--json] [--interactive] [--no-color] [--verbose]
1112
- [--api-key <value>] [--dir <value>] [--dry-run] [--push] [--recent <value>] [--reset] [--since <value>] [--staging]
1113
- [--workspace <value>]
1112
+ [--api-key <value>] [--dir <value>] [--dry-run] [--full-summary] [--push] [--recent <value>] [--reset] [--since
1113
+ <value>] [--staging] [--workspace <value>]
1114
1114
 
1115
1115
  FLAGS
1116
1116
  --api-key=<value> API key for the legacy source (or set LAUNCH_API_KEY)
@@ -1119,6 +1119,9 @@ FLAGS
1119
1119
  --dry-run Fetch and summarize changes without writing anything
1120
1120
  --from=<option> (required) Legacy source to migrate from
1121
1121
  <options: launch|launchdarkly|flagsmith>
1122
+ --full-summary Reify the full source-side audit log into per-change git commits (author = original user, date =
1123
+ original timestamp, message = change summary). Only valid on first-run imports — pass --reset to
1124
+ re-import everything from scratch with this flag.
1122
1125
  --push After migrating to a local dir, also push to the given --workspace on Quonfig cloud
1123
1126
  --recent=<value> Import only the last N changes (useful for tire-kicking)
1124
1127
  --reset Ignore the delta cursor and re-import everything from scratch
@@ -1154,7 +1157,7 @@ EXAMPLES
1154
1157
  $ qfg migrate --from launch --api-key $LAUNCH_API_KEY --dir ./quonfig-repo --staging
1155
1158
  ```
1156
1159
 
1157
- _See code: [src/commands/migrate.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/migrate.ts)_
1160
+ _See code: [src/commands/migrate.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/migrate.ts)_
1158
1161
 
1159
1162
  ## `qfg migrate doctor`
1160
1163
 
@@ -1192,7 +1195,7 @@ EXAMPLES
1192
1195
  $ qfg migrate doctor --json
1193
1196
  ```
1194
1197
 
1195
- _See code: [src/commands/migrate/doctor.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/migrate/doctor.ts)_
1198
+ _See code: [src/commands/migrate/doctor.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/migrate/doctor.ts)_
1196
1199
 
1197
1200
  ## `qfg migrate my-code`
1198
1201
 
@@ -1224,7 +1227,7 @@ EXAMPLES
1224
1227
  $ qfg migrate my-code --dry-run
1225
1228
  ```
1226
1229
 
1227
- _See code: [src/commands/migrate/my-code.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/migrate/my-code.ts)_
1230
+ _See code: [src/commands/migrate/my-code.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/migrate/my-code.ts)_
1228
1231
 
1229
1232
  ## `qfg migrate status`
1230
1233
 
@@ -1255,7 +1258,7 @@ EXAMPLES
1255
1258
  $ qfg migrate status --json
1256
1259
  ```
1257
1260
 
1258
- _See code: [src/commands/migrate/status.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/migrate/status.ts)_
1261
+ _See code: [src/commands/migrate/status.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/migrate/status.ts)_
1259
1262
 
1260
1263
  ## `qfg override [NAME] [VALUE]`
1261
1264
 
@@ -1310,7 +1313,7 @@ EXAMPLES
1310
1313
  $ qfg override my.flag true --env=staging
1311
1314
  ```
1312
1315
 
1313
- _See code: [src/commands/override.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/override.ts)_
1316
+ _See code: [src/commands/override.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/override.ts)_
1314
1317
 
1315
1318
  ## `qfg pull`
1316
1319
 
@@ -1322,7 +1325,8 @@ USAGE
1322
1325
  <value>]
1323
1326
 
1324
1327
  FLAGS
1325
- --dir=<value> Local directory to clone/update (defaults to QUONFIG_DIR env var)
1328
+ --dir=<value> Local directory to clone/update (defaults to cwd / nearest ancestor with quonfig.json /
1329
+ QUONFIG_DIR env var)
1326
1330
  --rebase Replay local commits on top of origin/main when the two have diverged. Conflicts are surfaced via
1327
1331
  standard git markers; resolve with `git rebase --continue`.
1328
1332
  --workspace=<value> Workspace ID (defaults to active profile)
@@ -1357,7 +1361,7 @@ EXAMPLES
1357
1361
  $ qfg pull # uses QUONFIG_DIR env var
1358
1362
  ```
1359
1363
 
1360
- _See code: [src/commands/pull.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/pull.ts)_
1364
+ _See code: [src/commands/pull.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/pull.ts)_
1361
1365
 
1362
1366
  ## `qfg push`
1363
1367
 
@@ -1370,7 +1374,8 @@ USAGE
1370
1374
 
1371
1375
  FLAGS
1372
1376
  -m, --message=<value> Commit message for bare-path pushes (ignored on clone-path; push what is already committed)
1373
- --dir=<value> Local directory to push (defaults to QUONFIG_DIR env var)
1377
+ --dir=<value> Local directory to push (defaults to cwd / nearest ancestor with quonfig.json / QUONFIG_DIR
1378
+ env var)
1374
1379
  --no-pin-write Do not offer to write workspace slug into quonfig.json on success
1375
1380
  --skip-validate Skip `qfg validate` preflight
1376
1381
  --workspace=<value> Workspace slug or UUID (defaults to active profile)
@@ -1391,7 +1396,7 @@ DESCRIPTION
1391
1396
  3. A diff summary is shown; destructive changes (10+ deletes, >=25% of
1392
1397
  files, or an unpinned dir) require typing the workspace slug to confirm.
1393
1398
 
1394
- qfg push # uses QUONFIG_DIR + profile workspace
1399
+ qfg push # resolves dir from cwd, QUONFIG_DIR, or --dir
1395
1400
  qfg push --dir ./our-config
1396
1401
  qfg push --dir ./our-config --workspace acme-prod
1397
1402
  qfg push --dir ./our-config --yes # skip normal Y/N (never skips typed-slug)
@@ -1405,7 +1410,7 @@ EXAMPLES
1405
1410
  $ qfg push --dir ./our-config --yes
1406
1411
  ```
1407
1412
 
1408
- _See code: [src/commands/push.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/push.ts)_
1413
+ _See code: [src/commands/push.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/push.ts)_
1409
1414
 
1410
1415
  ## `qfg run [COMMAND]`
1411
1416
 
@@ -1456,7 +1461,7 @@ EXAMPLES
1456
1461
  $ qfg run --env DATABASE_URL=db.url --preserve-env --environment=staging -- npm test
1457
1462
  ```
1458
1463
 
1459
- _See code: [src/commands/run.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/run.ts)_
1464
+ _See code: [src/commands/run.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/run.ts)_
1460
1465
 
1461
1466
  ## `qfg schema NAME`
1462
1467
 
@@ -1494,7 +1499,7 @@ EXAMPLES
1494
1499
  $ qfg schema my-schema --set-json-schema=@schemas/my-schema.json --protected
1495
1500
  ```
1496
1501
 
1497
- _See code: [src/commands/schema.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/schema.ts)_
1502
+ _See code: [src/commands/schema.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/schema.ts)_
1498
1503
 
1499
1504
  ## `qfg sdk-key`
1500
1505
 
@@ -1521,7 +1526,7 @@ EXAMPLES
1521
1526
  $ qfg sdk-key revoke <key-id>
1522
1527
  ```
1523
1528
 
1524
- _See code: [src/commands/sdk-key.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/sdk-key.ts)_
1529
+ _See code: [src/commands/sdk-key.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/sdk-key.ts)_
1525
1530
 
1526
1531
  ## `qfg sdk-key create`
1527
1532
 
@@ -1553,7 +1558,7 @@ EXAMPLES
1553
1558
  $ qfg sdk-key create --environment staging --type browser
1554
1559
  ```
1555
1560
 
1556
- _See code: [src/commands/sdk-key/create.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/sdk-key/create.ts)_
1561
+ _See code: [src/commands/sdk-key/create.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/sdk-key/create.ts)_
1557
1562
 
1558
1563
  ## `qfg sdk-key list`
1559
1564
 
@@ -1582,7 +1587,7 @@ EXAMPLES
1582
1587
  $ qfg sdk-key list --environment production
1583
1588
  ```
1584
1589
 
1585
- _See code: [src/commands/sdk-key/list.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/sdk-key/list.ts)_
1590
+ _See code: [src/commands/sdk-key/list.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/sdk-key/list.ts)_
1586
1591
 
1587
1592
  ## `qfg sdk-key revoke KEYID`
1588
1593
 
@@ -1609,7 +1614,7 @@ EXAMPLES
1609
1614
  $ qfg sdk-key revoke a1b2c3d4-e5f6-7890-abcd-ef1234567890
1610
1615
  ```
1611
1616
 
1612
- _See code: [src/commands/sdk-key/revoke.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/sdk-key/revoke.ts)_
1617
+ _See code: [src/commands/sdk-key/revoke.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/sdk-key/revoke.ts)_
1613
1618
 
1614
1619
  ## `qfg set-default [NAME]`
1615
1620
 
@@ -1680,7 +1685,7 @@ EXAMPLES
1680
1685
  $ qfg pull && qfg config-schema
1681
1686
  ```
1682
1687
 
1683
- _See code: [src/commands/set-default.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/set-default.ts)_
1688
+ _See code: [src/commands/set-default.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/set-default.ts)_
1684
1689
 
1685
1690
  ## `qfg set-rollout [NAME]`
1686
1691
 
@@ -1757,7 +1762,7 @@ EXAMPLES
1757
1762
  $ qfg set-rollout my.variant.flag --environment production --weights "a:33,b:33,c:34" --hash-by user.id
1758
1763
  ```
1759
1764
 
1760
- _See code: [src/commands/set-rollout.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/set-rollout.ts)_
1765
+ _See code: [src/commands/set-rollout.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/set-rollout.ts)_
1761
1766
 
1762
1767
  ## `qfg sync`
1763
1768
 
@@ -1789,7 +1794,7 @@ EXAMPLES
1789
1794
  $ qfg sync --watch --dir ./our-config --interval 30
1790
1795
  ```
1791
1796
 
1792
- _See code: [src/commands/sync.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/sync.ts)_
1797
+ _See code: [src/commands/sync.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/sync.ts)_
1793
1798
 
1794
1799
  ## `qfg toggle [NAME]`
1795
1800
 
@@ -1891,7 +1896,7 @@ EXAMPLES
1891
1896
  $ qfg verify --json
1892
1897
  ```
1893
1898
 
1894
- _See code: [src/commands/verify.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/verify.ts)_
1899
+ _See code: [src/commands/verify.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/verify.ts)_
1895
1900
 
1896
1901
  ## `qfg whoami`
1897
1902
 
@@ -1914,7 +1919,7 @@ EXAMPLES
1914
1919
  $ qfg whoami
1915
1920
  ```
1916
1921
 
1917
- _See code: [src/commands/whoami.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/whoami.ts)_
1922
+ _See code: [src/commands/whoami.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/whoami.ts)_
1918
1923
 
1919
1924
  ## `qfg workspace`
1920
1925
 
@@ -1937,7 +1942,7 @@ EXAMPLES
1937
1942
  $ qfg workspace
1938
1943
  ```
1939
1944
 
1940
- _See code: [src/commands/workspace.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/workspace.ts)_
1945
+ _See code: [src/commands/workspace.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/workspace.ts)_
1941
1946
 
1942
1947
  ## `qfg workspace bootstrap`
1943
1948
 
@@ -1970,7 +1975,7 @@ EXAMPLES
1970
1975
  $ qfg workspace bootstrap --dir ./our-config --skip-validate
1971
1976
  ```
1972
1977
 
1973
- _See code: [src/commands/workspace/bootstrap.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/workspace/bootstrap.ts)_
1978
+ _See code: [src/commands/workspace/bootstrap.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/workspace/bootstrap.ts)_
1974
1979
 
1975
1980
  ## `qfg workspace create SLUG`
1976
1981
 
@@ -2004,7 +2009,7 @@ EXAMPLES
2004
2009
  $ qfg workspace create my-team --org 11111111-1111-1111-1111-111111111111
2005
2010
  ```
2006
2011
 
2007
- _See code: [src/commands/workspace/create.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/workspace/create.ts)_
2012
+ _See code: [src/commands/workspace/create.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/workspace/create.ts)_
2008
2013
 
2009
2014
  ## `qfg workspace switch [SLUG]`
2010
2015
 
@@ -2032,7 +2037,7 @@ EXAMPLES
2032
2037
  $ qfg workspace switch acme/production
2033
2038
  ```
2034
2039
 
2035
- _See code: [src/commands/workspace/switch.ts](https://github.com/quonfig/cli/blob/v0.0.45/src/commands/workspace/switch.ts)_
2040
+ _See code: [src/commands/workspace/switch.ts](https://github.com/quonfig/cli/blob/v0.0.47/src/commands/workspace/switch.ts)_
2036
2041
  <!-- commandsstop -->
2037
2042
 
2038
2043
  ## Local Development
@@ -8,6 +8,7 @@ export default class Migrate extends BaseCommand {
8
8
  dir: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
9
9
  'dry-run': import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
10
10
  from: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
11
+ 'full-summary': import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
11
12
  push: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
12
13
  recent: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
13
14
  reset: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
@@ -45,6 +45,12 @@ export default class Migrate extends BaseCommand {
45
45
  options: ['launch', 'launchdarkly', 'flagsmith'],
46
46
  required: true,
47
47
  }),
48
+ 'full-summary': Flags.boolean({
49
+ default: false,
50
+ description: 'Reify the full source-side audit log into per-change git commits ' +
51
+ '(author = original user, date = original timestamp, message = change summary). ' +
52
+ 'Only valid on first-run imports — pass --reset to re-import everything from scratch with this flag.',
53
+ }),
48
54
  push: Flags.boolean({
49
55
  default: false,
50
56
  description: 'After migrating to a local dir, also push to the given --workspace on Quonfig cloud',
@@ -76,6 +82,10 @@ export default class Migrate extends BaseCommand {
76
82
  if (!flags['api-key']) {
77
83
  return this.err('--api-key is required. For --from launch you can also set LAUNCH_API_KEY in your environment.');
78
84
  }
85
+ if (flags['full-summary'] && flags.recent !== undefined) {
86
+ return this.err('--full-summary and --recent are incompatible: --full-summary reifies the entire audit log into git history, ' +
87
+ 'so trimming changes with --recent would produce a misleading partial log. Drop one of the flags.');
88
+ }
79
89
  let workspaceContext = null;
80
90
  if (flags.push) {
81
91
  const resolved = await this.resolvePushWorkspace(flags.workspace);
@@ -94,6 +104,16 @@ export default class Migrate extends BaseCommand {
94
104
  throw error;
95
105
  }
96
106
  }
107
+ // qfg-wbkj: --full-summary is a one-shot first-run import. Re-running it on
108
+ // top of an incremental migration would produce a mixed history (one
109
+ // collapsed commit on the bottom, per-change commits on top) which is
110
+ // worse than either pure mode. Force the customer to either drop the flag
111
+ // or explicitly --reset.
112
+ if (flags['full-summary'] && !flags.reset && readImportState(dir) !== null) {
113
+ return this.err('--full-summary is only valid on first-run imports, but this directory has already been migrated incrementally ' +
114
+ '(.qf/import-state.json exists). Either drop --full-summary to continue the incremental import, ' +
115
+ 'or re-import everything from scratch by passing --reset alongside --full-summary into a fresh directory.');
116
+ }
97
117
  if (flags.from === 'launch') {
98
118
  applyLaunchBaseUrl(flags.staging);
99
119
  }
@@ -146,11 +166,14 @@ export default class Migrate extends BaseCommand {
146
166
  const importState = { source: flags.from };
147
167
  if (latestChangedAt !== undefined)
148
168
  importState.lastProcessedAt = latestChangedAt;
149
- this.log(`Pushing ${toProcess.length} change(s) to workspace ${workspaceId} (clone-and-stack)...`);
169
+ this.log(flags['full-summary']
170
+ ? `Pushing ${toProcess.length} change(s) to workspace ${workspaceId} as per-change audit-log commits...`
171
+ : `Pushing ${toProcess.length} change(s) to workspace ${workspaceId} (clone-and-stack)...`);
150
172
  try {
151
173
  const result = await pushMigrationToCloud({
152
174
  changes: toProcess,
153
175
  environments,
176
+ fullHistory: flags['full-summary'],
154
177
  importState,
155
178
  localDir: dir,
156
179
  remoteUrl: repoUrl,
@@ -197,6 +220,7 @@ export default class Migrate extends BaseCommand {
197
220
  const localResult = await applyLocalMigration({
198
221
  changes: toProcess,
199
222
  environments,
223
+ fullHistory: flags['full-summary'],
200
224
  importState: localImportState,
201
225
  localDir: dir,
202
226
  reportData: buildReportData(flags.from),
@@ -1,12 +1,13 @@
1
- import * as path from 'node:path';
2
1
  import * as fs from 'node:fs';
3
2
  import { Flags } from '@oclif/core';
4
3
  import { BaseCommand } from '../index.js';
5
4
  import { loadGiteaToken, isGiteaTokenExpired, saveGiteaToken } from '../util/gitea-token-storage.js';
6
5
  import { mintAndStoreGiteaReadToken, mintGiteaToken } from '../util/gitea-api.js';
7
6
  import { readWorkspaceSlug, tryParseWorkspacePin, writeWorkspaceSlug } from '../util/quonfig-json.js';
7
+ import { resolveWorkspaceDir } from '../util/resolve-workspace-dir.js';
8
8
  import { resolveWorkspaceUuid } from '../util/resolve-workspace.js';
9
- import { isGitRepo, getRemoteUrl, gitFetch, gitSetRemote, canFastForward, hasDivergedFromRemote, gitMergeFfOnly, gitPullRebase, gitClone, displayUrl, addAndCommitFile, dirtyTrackedFiles, } from '../util/git-ops.js';
9
+ import { isGitRepo, getAllRemoteUrls, getRemoteUrl, gitFetch, gitSetRemote, canFastForward, hasDivergedFromRemote, gitMergeFfOnly, gitPullRebase, gitClone, displayUrl, addAndCommitFile, dirtyTrackedFiles, } from '../util/git-ops.js';
10
+ import { findQuonfigRemote } from '../push/identity-check.js';
10
11
  export default class Pull extends BaseCommand {
11
12
  static description = `Clone or update a local copy of your workspace config files.
12
13
 
@@ -27,7 +28,7 @@ CLI shortcuts (no JSON editing needed for simple cases):
27
28
  static examples = ['<%= config.bin %> pull --dir ./our-config', '<%= config.bin %> pull # uses QUONFIG_DIR env var'];
28
29
  static flags = {
29
30
  dir: Flags.string({
30
- description: 'Local directory to clone/update (defaults to QUONFIG_DIR env var)',
31
+ description: 'Local directory to clone/update (defaults to cwd / nearest ancestor with quonfig.json / QUONFIG_DIR env var)',
31
32
  }),
32
33
  rebase: Flags.boolean({
33
34
  default: false,
@@ -39,12 +40,18 @@ CLI shortcuts (no JSON editing needed for simple cases):
39
40
  };
40
41
  async run() {
41
42
  const { flags } = await this.parse(Pull);
42
- // Resolve target directory
43
- const dir = flags.dir || process.env.QUONFIG_DIR;
44
- if (!dir) {
45
- return this.err('No directory specified. Use --dir <path> or set QUONFIG_DIR.');
43
+ // Resolve target directory. The cwd walk is for the "already inside a
44
+ // workspace" case; for a first-time clone the user passes --dir
45
+ // explicitly (no quonfig.json exists yet, so the walk would fail).
46
+ const resolved = resolveWorkspaceDir({
47
+ flagDir: flags.dir,
48
+ envDir: process.env.QUONFIG_DIR,
49
+ cwd: process.cwd(),
50
+ });
51
+ if (resolved.kind === 'error') {
52
+ return this.err(resolved.message);
46
53
  }
47
- const resolvedDir = path.resolve(dir);
54
+ const resolvedDir = resolved.dir;
48
55
  // Resolve workspace ID — supports both OAuth and QUONFIG_API_KEY paths,
49
56
  // mirroring what APICommand does via get-client.ts so `qfg pull` behaves
50
57
  // the same in CI as `qfg create` or `qfg push`.
@@ -56,11 +63,37 @@ CLI shortcuts (no JSON editing needed for simple cases):
56
63
  // Perform git operation
57
64
  const isRepo = await isGitRepo(resolvedDir);
58
65
  if (isRepo) {
59
- // Existing repo — check remote
60
- const existingRemote = await getRemoteUrl(resolvedDir);
66
+ // Multi-remote support (qfg-glrd.3): walk every configured remote to
67
+ // find one whose URL matches the backend repo. Customers commonly run
68
+ // `origin = github.com/<org>/configs` for PR review with a secondary
69
+ // remote pointing at Quonfig — a single-remote check would falsely
70
+ // abort here. We accept as long as ANY configured remote matches.
71
+ const allRemotes = await getAllRemoteUrls(resolvedDir);
72
+ const matchingRemote = findQuonfigRemote(allRemotes, repoUrl);
61
73
  const expectedUrlBase = stripAuth(repoUrl);
62
- if (existingRemote && stripAuth(existingRemote) !== expectedUrlBase) {
63
- return this.err(`Directory has a different git remote:\n existing: ${displayUrl(existingRemote)}\n expected: ${expectedUrlBase}\n\nResolve manually or use a different --dir.`);
74
+ if (allRemotes.length > 0 && !matchingRemote) {
75
+ // No configured remote points at the Quonfig backend. List every
76
+ // remote we considered so the user can see what's misconfigured —
77
+ // refuse BEFORE fetching anything from the wrong target.
78
+ const remoteList = allRemotes.map((r) => ` - ${displayUrl(r)}`).join('\n');
79
+ return this.err(`No configured git remote matches the Quonfig backend.\n` +
80
+ `Configured remotes:\n${remoteList}\n` +
81
+ `Expected: ${expectedUrlBase}\n\n` +
82
+ `Resolve manually or use a different --dir.`);
83
+ }
84
+ // The Quonfig-matching remote must be `origin` for the current pull
85
+ // flow, which fetches `origin` and merges `origin/main`. If a non-
86
+ // origin remote matches, tell the user how to align — refusing
87
+ // cleanly is safer than silently rewriting `origin` (which would
88
+ // clobber their PR-review remote URL).
89
+ const originRemote = await getRemoteUrl(resolvedDir);
90
+ const originMatches = originRemote !== null && stripAuth(originRemote) === expectedUrlBase;
91
+ if (matchingRemote && !originMatches) {
92
+ return this.err(`qfg pull requires the Quonfig remote to be named "origin".\n` +
93
+ `A matching remote was found, but it is not origin:\n` +
94
+ ` matching remote: ${displayUrl(matchingRemote)}\n` +
95
+ ` origin: ${originRemote ? displayUrl(originRemote) : '(unset)'}\n\n` +
96
+ `Rename the Quonfig remote to origin (replacing the current origin), or set origin to ${expectedUrlBase}.`);
64
97
  }
65
98
  // Update the remote URL to use current (possibly refreshed) token
66
99
  await gitSetRemote(resolvedDir, repoUrl);