@quonfig/cli 0.0.52 → 0.0.53

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.52 linux-x64 node-v24.4.1
20
+ @quonfig/cli/0.0.53 linux-x64 node-v24.4.1
21
21
  $ qfg --help [COMMAND]
22
22
  USAGE
23
23
  $ qfg COMMAND
@@ -157,6 +157,7 @@ script doesn't need to know which env it's running in.
157
157
  * [`qfg sdk-key create`](#qfg-sdk-key-create)
158
158
  * [`qfg sdk-key list`](#qfg-sdk-key-list)
159
159
  * [`qfg sdk-key revoke KEYID`](#qfg-sdk-key-revoke-keyid)
160
+ * [`qfg serve`](#qfg-serve)
160
161
  * [`qfg set-default [NAME]`](#qfg-set-default-name)
161
162
  * [`qfg set-rollout [NAME]`](#qfg-set-rollout-name)
162
163
  * [`qfg sync`](#qfg-sync)
@@ -195,7 +196,7 @@ EXAMPLES
195
196
  $ qfg activity restore my.flag --yes
196
197
  ```
197
198
 
198
- _See code: [src/commands/activity.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/activity.ts)_
199
+ _See code: [src/commands/activity.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/activity.ts)_
199
200
 
200
201
  ## `qfg activity deleted`
201
202
 
@@ -224,7 +225,7 @@ EXAMPLES
224
225
  $ qfg activity deleted --json
225
226
  ```
226
227
 
227
- _See code: [src/commands/activity/deleted.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/activity/deleted.ts)_
228
+ _See code: [src/commands/activity/deleted.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/activity/deleted.ts)_
228
229
 
229
230
  ## `qfg activity feed`
230
231
 
@@ -259,7 +260,7 @@ EXAMPLES
259
260
  $ qfg activity feed --json
260
261
  ```
261
262
 
262
- _See code: [src/commands/activity/feed.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/activity/feed.ts)_
263
+ _See code: [src/commands/activity/feed.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/activity/feed.ts)_
263
264
 
264
265
  ## `qfg activity history [NAME]`
265
266
 
@@ -293,7 +294,7 @@ EXAMPLES
293
294
  $ qfg activity history request.timeout --json
294
295
  ```
295
296
 
296
- _See code: [src/commands/activity/history.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/activity/history.ts)_
297
+ _See code: [src/commands/activity/history.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/activity/history.ts)_
297
298
 
298
299
  ## `qfg activity restore [NAME]`
299
300
 
@@ -332,7 +333,7 @@ EXAMPLES
332
333
  $ qfg activity restore request.timeout --type config --yes
333
334
  ```
334
335
 
335
- _See code: [src/commands/activity/restore.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/activity/restore.ts)_
336
+ _See code: [src/commands/activity/restore.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/activity/restore.ts)_
336
337
 
337
338
  ## `qfg audit-log [NAME]`
338
339
 
@@ -360,7 +361,7 @@ EXAMPLES
360
361
  $ qfg audit-log my.flag
361
362
  ```
362
363
 
363
- _See code: [src/commands/audit-log.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/audit-log.ts)_
364
+ _See code: [src/commands/audit-log.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/audit-log.ts)_
364
365
 
365
366
  ## `qfg config-schema`
366
367
 
@@ -389,7 +390,7 @@ EXAMPLES
389
390
  $ qfg config-schema --json-schema # full JSON Schema document (copy into your editor)
390
391
  ```
391
392
 
392
- _See code: [src/commands/config-schema.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/config-schema.ts)_
393
+ _See code: [src/commands/config-schema.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/config-schema.ts)_
393
394
 
394
395
  ## `qfg create NAME`
395
396
 
@@ -474,7 +475,7 @@ EXAMPLES
474
475
  $ qfg set-rollout my.new.flag --environment production --true-percent 20
475
476
  ```
476
477
 
477
- _See code: [src/commands/create.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/create.ts)_
478
+ _See code: [src/commands/create.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/create.ts)_
478
479
 
479
480
  ## `qfg delete NAME`
480
481
 
@@ -520,7 +521,7 @@ EXAMPLES
520
521
  $ qfg delete my.config --yes
521
522
  ```
522
523
 
523
- _See code: [src/commands/delete.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/delete.ts)_
524
+ _See code: [src/commands/delete.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/delete.ts)_
524
525
 
525
526
  ## `qfg flag info [NAME]`
526
527
 
@@ -724,7 +725,7 @@ EXAMPLES
724
725
  $ qfg generate --targets node-ts -o ./dist # combine with targets
725
726
  ```
726
727
 
727
- _See code: [src/commands/generate.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/generate.ts)_
728
+ _See code: [src/commands/generate.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/generate.ts)_
728
729
 
729
730
  ## `qfg generate-new-hex-key`
730
731
 
@@ -747,7 +748,7 @@ EXAMPLES
747
748
  $ qfg generate-new-hex-key
748
749
  ```
749
750
 
750
- _See code: [src/commands/generate-new-hex-key.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/generate-new-hex-key.ts)_
751
+ _See code: [src/commands/generate-new-hex-key.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/generate-new-hex-key.ts)_
751
752
 
752
753
  ## `qfg get [NAME]`
753
754
 
@@ -779,7 +780,7 @@ EXAMPLES
779
780
  $ qfg get my.config.name --environment=production
780
781
  ```
781
782
 
782
- _See code: [src/commands/get.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/get.ts)_
783
+ _See code: [src/commands/get.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/get.ts)_
783
784
 
784
785
  ## `qfg history NAME`
785
786
 
@@ -805,7 +806,7 @@ EXAMPLES
805
806
  $ qfg history my.flag
806
807
  ```
807
808
 
808
- _See code: [src/commands/history.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/history.ts)_
809
+ _See code: [src/commands/history.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/history.ts)_
809
810
 
810
811
  ## `qfg info [NAME]`
811
812
 
@@ -853,7 +854,7 @@ EXAMPLES
853
854
  $ qfg info my.config.name --exclude-evaluations # skip 24h stats
854
855
  ```
855
856
 
856
- _See code: [src/commands/info.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/info.ts)_
857
+ _See code: [src/commands/info.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/info.ts)_
857
858
 
858
859
  ## `qfg init [DIRECTORY]`
859
860
 
@@ -893,7 +894,7 @@ EXAMPLES
893
894
  $ qfg init --dry-run
894
895
  ```
895
896
 
896
- _See code: [src/commands/init.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/init.ts)_
897
+ _See code: [src/commands/init.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/init.ts)_
897
898
 
898
899
  ## `qfg interactive`
899
900
 
@@ -923,7 +924,7 @@ EXAMPLES
923
924
  $ qfg
924
925
  ```
925
926
 
926
- _See code: [src/commands/interactive.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/interactive.ts)_
927
+ _See code: [src/commands/interactive.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/interactive.ts)_
927
928
 
928
929
  ## `qfg list`
929
930
 
@@ -963,7 +964,7 @@ EXAMPLES
963
964
  $ qfg list --feature-flags
964
965
  ```
965
966
 
966
- _See code: [src/commands/list.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/list.ts)_
967
+ _See code: [src/commands/list.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/list.ts)_
967
968
 
968
969
  ## `qfg log`
969
970
 
@@ -988,7 +989,7 @@ EXAMPLES
988
989
  $ qfg log --limit 5
989
990
  ```
990
991
 
991
- _See code: [src/commands/log.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/log.ts)_
992
+ _See code: [src/commands/log.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/log.ts)_
992
993
 
993
994
  ## `qfg log-level NAME`
994
995
 
@@ -1053,7 +1054,7 @@ EXAMPLES
1053
1054
  $ qfg log-level log-level.my-app --target=Chatty --value=INFO --environment=production
1054
1055
  ```
1055
1056
 
1056
- _See code: [src/commands/log-level.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/log-level.ts)_
1057
+ _See code: [src/commands/log-level.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/log-level.ts)_
1057
1058
 
1058
1059
  ## `qfg login`
1059
1060
 
@@ -1078,7 +1079,7 @@ EXAMPLES
1078
1079
  $ qfg login --profile myprofile
1079
1080
  ```
1080
1081
 
1081
- _See code: [src/commands/login.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/login.ts)_
1082
+ _See code: [src/commands/login.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/login.ts)_
1082
1083
 
1083
1084
  ## `qfg logout`
1084
1085
 
@@ -1101,7 +1102,7 @@ EXAMPLES
1101
1102
  $ qfg logout
1102
1103
  ```
1103
1104
 
1104
- _See code: [src/commands/logout.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/logout.ts)_
1105
+ _See code: [src/commands/logout.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/logout.ts)_
1105
1106
 
1106
1107
  ## `qfg migrate`
1107
1108
 
@@ -1164,7 +1165,7 @@ EXAMPLES
1164
1165
  $ qfg migrate --from launch --source-api-key $LAUNCH_API_KEY --dir ./quonfig-repo --staging
1165
1166
  ```
1166
1167
 
1167
- _See code: [src/commands/migrate.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/migrate.ts)_
1168
+ _See code: [src/commands/migrate.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/migrate.ts)_
1168
1169
 
1169
1170
  ## `qfg migrate doctor`
1170
1171
 
@@ -1202,7 +1203,7 @@ EXAMPLES
1202
1203
  $ qfg migrate doctor --json
1203
1204
  ```
1204
1205
 
1205
- _See code: [src/commands/migrate/doctor.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/migrate/doctor.ts)_
1206
+ _See code: [src/commands/migrate/doctor.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/migrate/doctor.ts)_
1206
1207
 
1207
1208
  ## `qfg migrate my-code`
1208
1209
 
@@ -1234,7 +1235,7 @@ EXAMPLES
1234
1235
  $ qfg migrate my-code --dry-run
1235
1236
  ```
1236
1237
 
1237
- _See code: [src/commands/migrate/my-code.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/migrate/my-code.ts)_
1238
+ _See code: [src/commands/migrate/my-code.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/migrate/my-code.ts)_
1238
1239
 
1239
1240
  ## `qfg migrate status`
1240
1241
 
@@ -1265,7 +1266,7 @@ EXAMPLES
1265
1266
  $ qfg migrate status --json
1266
1267
  ```
1267
1268
 
1268
- _See code: [src/commands/migrate/status.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/migrate/status.ts)_
1269
+ _See code: [src/commands/migrate/status.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/migrate/status.ts)_
1269
1270
 
1270
1271
  ## `qfg override [NAME] [VALUE]`
1271
1272
 
@@ -1320,7 +1321,7 @@ EXAMPLES
1320
1321
  $ qfg override my.flag true --env=staging
1321
1322
  ```
1322
1323
 
1323
- _See code: [src/commands/override.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/override.ts)_
1324
+ _See code: [src/commands/override.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/override.ts)_
1324
1325
 
1325
1326
  ## `qfg pull`
1326
1327
 
@@ -1368,7 +1369,7 @@ EXAMPLES
1368
1369
  $ qfg pull # uses QUONFIG_DIR env var
1369
1370
  ```
1370
1371
 
1371
- _See code: [src/commands/pull.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/pull.ts)_
1372
+ _See code: [src/commands/pull.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/pull.ts)_
1372
1373
 
1373
1374
  ## `qfg push`
1374
1375
 
@@ -1417,7 +1418,7 @@ EXAMPLES
1417
1418
  $ qfg push --dir ./our-config --yes
1418
1419
  ```
1419
1420
 
1420
- _See code: [src/commands/push.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/push.ts)_
1421
+ _See code: [src/commands/push.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/push.ts)_
1421
1422
 
1422
1423
  ## `qfg run [COMMAND]`
1423
1424
 
@@ -1468,7 +1469,7 @@ EXAMPLES
1468
1469
  $ qfg run --env DATABASE_URL=db.url --preserve-env --environment=staging -- npm test
1469
1470
  ```
1470
1471
 
1471
- _See code: [src/commands/run.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/run.ts)_
1472
+ _See code: [src/commands/run.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/run.ts)_
1472
1473
 
1473
1474
  ## `qfg schema NAME`
1474
1475
 
@@ -1506,7 +1507,7 @@ EXAMPLES
1506
1507
  $ qfg schema my-schema --set-json-schema=@schemas/my-schema.json --protected
1507
1508
  ```
1508
1509
 
1509
- _See code: [src/commands/schema.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/schema.ts)_
1510
+ _See code: [src/commands/schema.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/schema.ts)_
1510
1511
 
1511
1512
  ## `qfg sdk-key`
1512
1513
 
@@ -1533,7 +1534,7 @@ EXAMPLES
1533
1534
  $ qfg sdk-key revoke <key-id>
1534
1535
  ```
1535
1536
 
1536
- _See code: [src/commands/sdk-key.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/sdk-key.ts)_
1537
+ _See code: [src/commands/sdk-key.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/sdk-key.ts)_
1537
1538
 
1538
1539
  ## `qfg sdk-key create`
1539
1540
 
@@ -1565,7 +1566,7 @@ EXAMPLES
1565
1566
  $ qfg sdk-key create --environment staging --type browser
1566
1567
  ```
1567
1568
 
1568
- _See code: [src/commands/sdk-key/create.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/sdk-key/create.ts)_
1569
+ _See code: [src/commands/sdk-key/create.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/sdk-key/create.ts)_
1569
1570
 
1570
1571
  ## `qfg sdk-key list`
1571
1572
 
@@ -1594,7 +1595,7 @@ EXAMPLES
1594
1595
  $ qfg sdk-key list --environment production
1595
1596
  ```
1596
1597
 
1597
- _See code: [src/commands/sdk-key/list.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/sdk-key/list.ts)_
1598
+ _See code: [src/commands/sdk-key/list.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/sdk-key/list.ts)_
1598
1599
 
1599
1600
  ## `qfg sdk-key revoke KEYID`
1600
1601
 
@@ -1621,7 +1622,64 @@ EXAMPLES
1621
1622
  $ qfg sdk-key revoke a1b2c3d4-e5f6-7890-abcd-ef1234567890
1622
1623
  ```
1623
1624
 
1624
- _See code: [src/commands/sdk-key/revoke.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/sdk-key/revoke.ts)_
1625
+ _See code: [src/commands/sdk-key/revoke.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/sdk-key/revoke.ts)_
1626
+
1627
+ ## `qfg serve`
1628
+
1629
+ Serve a local datadir over HTTP to browser/RN SDKs.
1630
+
1631
+ ```
1632
+ USAGE
1633
+ $ qfg serve [--json] [--interactive] [--no-color] [--verbose] [--datadir <value>] [--environment <value>]
1634
+ [--port <value>] [--host <value>] [--frontend-sdk-key <value>] [--cors-origin <value>...] [--watch]
1635
+ [--allow-non-loopback]
1636
+
1637
+ FLAGS
1638
+ --allow-non-loopback Confirm a LAN-reachable bind. Required when --host is not loopback.
1639
+ --cors-origin=<value>... [default: *] Allowed CORS origin (repeatable). Default is *; required when binding to a
1640
+ non-loopback host.
1641
+ --datadir=<value> Datadir to serve (defaults to ./our-config, then ./.quonfig, then errors). Honors
1642
+ QUONFIG_DIR.
1643
+ --environment=<value> [default: development] Which environment slug to evaluate. Honors QUONFIG_ENVIRONMENT.
1644
+ --frontend-sdk-key=<value> If set, every request must present Authorization: Basic 1:<key>. If unset, the server is
1645
+ open (matches the "datadir is the source of truth" mental model).
1646
+ --host=<value> [default: 127.0.0.1] Bind address. Loopback by default; non-loopback requires
1647
+ --allow-non-loopback.
1648
+ --port=<value> [default: 6580] TCP port to listen on. Errors on collision; pass --port <n> to retry.
1649
+ --[no-]watch Reload the envelope when the datadir changes. --no-watch disables.
1650
+
1651
+ GLOBAL FLAGS
1652
+ --[no-]interactive Force interactive mode
1653
+ --json Format output as json.
1654
+ --no-color Do not colorize output
1655
+ --verbose Verbose output
1656
+
1657
+ DESCRIPTION
1658
+ Serve a local datadir over HTTP to browser/RN SDKs.
1659
+
1660
+ Reads configs from a local datadir and exposes them at
1661
+ `GET /api/v2/configs/eval-with-context/{base64url(ctx)}`. Point your
1662
+ browser SDK at the resulting URL (`http://localhost:6580` by default)
1663
+ and the same client code that talks to api-delivery in production will
1664
+ work unmodified.
1665
+
1666
+ Telemetry is intentionally not served — qfg serve has no Quonfig backend
1667
+ behind it. Disable client-side telemetry with
1668
+ `collectEvaluationSummaries: false` (and `contextUploadMode: "none"`),
1669
+ or point the SDK's `telemetryUrl` at a real endpoint.
1670
+
1671
+ The server is bound to 127.0.0.1 by default; pass --allow-non-loopback
1672
+ to confirm a LAN-reachable bind.
1673
+
1674
+ EXAMPLES
1675
+ $ qfg serve
1676
+
1677
+ $ qfg serve --datadir ./our-config --environment production
1678
+
1679
+ $ qfg serve --port 6581 --frontend-sdk-key PUBLIC_KEY
1680
+ ```
1681
+
1682
+ _See code: [src/commands/serve.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/serve.ts)_
1625
1683
 
1626
1684
  ## `qfg set-default [NAME]`
1627
1685
 
@@ -1692,7 +1750,7 @@ EXAMPLES
1692
1750
  $ qfg pull && qfg config-schema
1693
1751
  ```
1694
1752
 
1695
- _See code: [src/commands/set-default.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/set-default.ts)_
1753
+ _See code: [src/commands/set-default.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/set-default.ts)_
1696
1754
 
1697
1755
  ## `qfg set-rollout [NAME]`
1698
1756
 
@@ -1769,7 +1827,7 @@ EXAMPLES
1769
1827
  $ qfg set-rollout my.variant.flag --environment production --weights "a:33,b:33,c:34" --hash-by user.id
1770
1828
  ```
1771
1829
 
1772
- _See code: [src/commands/set-rollout.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/set-rollout.ts)_
1830
+ _See code: [src/commands/set-rollout.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/set-rollout.ts)_
1773
1831
 
1774
1832
  ## `qfg sync`
1775
1833
 
@@ -1801,7 +1859,7 @@ EXAMPLES
1801
1859
  $ qfg sync --watch --dir ./our-config --interval 30
1802
1860
  ```
1803
1861
 
1804
- _See code: [src/commands/sync.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/sync.ts)_
1862
+ _See code: [src/commands/sync.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/sync.ts)_
1805
1863
 
1806
1864
  ## `qfg toggle [NAME]`
1807
1865
 
@@ -1903,7 +1961,7 @@ EXAMPLES
1903
1961
  $ qfg verify --json
1904
1962
  ```
1905
1963
 
1906
- _See code: [src/commands/verify.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/verify.ts)_
1964
+ _See code: [src/commands/verify.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/verify.ts)_
1907
1965
 
1908
1966
  ## `qfg whoami`
1909
1967
 
@@ -1926,7 +1984,7 @@ EXAMPLES
1926
1984
  $ qfg whoami
1927
1985
  ```
1928
1986
 
1929
- _See code: [src/commands/whoami.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/whoami.ts)_
1987
+ _See code: [src/commands/whoami.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/whoami.ts)_
1930
1988
 
1931
1989
  ## `qfg workspace`
1932
1990
 
@@ -1949,7 +2007,7 @@ EXAMPLES
1949
2007
  $ qfg workspace
1950
2008
  ```
1951
2009
 
1952
- _See code: [src/commands/workspace.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/workspace.ts)_
2010
+ _See code: [src/commands/workspace.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/workspace.ts)_
1953
2011
 
1954
2012
  ## `qfg workspace bootstrap`
1955
2013
 
@@ -1982,7 +2040,7 @@ EXAMPLES
1982
2040
  $ qfg workspace bootstrap --dir ./our-config --skip-validate
1983
2041
  ```
1984
2042
 
1985
- _See code: [src/commands/workspace/bootstrap.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/workspace/bootstrap.ts)_
2043
+ _See code: [src/commands/workspace/bootstrap.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/workspace/bootstrap.ts)_
1986
2044
 
1987
2045
  ## `qfg workspace create SLUG`
1988
2046
 
@@ -2016,7 +2074,7 @@ EXAMPLES
2016
2074
  $ qfg workspace create my-team --org 11111111-1111-1111-1111-111111111111
2017
2075
  ```
2018
2076
 
2019
- _See code: [src/commands/workspace/create.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/workspace/create.ts)_
2077
+ _See code: [src/commands/workspace/create.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/workspace/create.ts)_
2020
2078
 
2021
2079
  ## `qfg workspace switch [SLUG]`
2022
2080
 
@@ -2044,7 +2102,7 @@ EXAMPLES
2044
2102
  $ qfg workspace switch acme/production
2045
2103
  ```
2046
2104
 
2047
- _See code: [src/commands/workspace/switch.ts](https://github.com/quonfig/cli/blob/v0.0.52/src/commands/workspace/switch.ts)_
2105
+ _See code: [src/commands/workspace/switch.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/workspace/switch.ts)_
2048
2106
  <!-- commandsstop -->
2049
2107
 
2050
2108
  ## Local Development
@@ -241,7 +241,6 @@ The flag separator '--' is REQUIRED between qfg flags and the child command.`;
241
241
  const quonfig = new Quonfig({
242
242
  sdkKey,
243
243
  collectEvaluationSummaries: false,
244
- collectLoggerCounts: false,
245
244
  contextUploadMode: 'none',
246
245
  enableSSE: false,
247
246
  apiUrls: [getDeliveryUrl()],
@@ -0,0 +1,23 @@
1
+ /**
2
+ * `qfg serve` — Node-native local server that exposes a datadir over the
3
+ * same HTTP protocol the browser SDKs already speak. Designed to close the
4
+ * "browser SDKs can't read a local datadir" gap (epic qfg-38sf, plan
5
+ * project/plans/qfg-serve.md, Option A).
6
+ */
7
+ import type { JsonObj } from '../result.js';
8
+ import { BaseCommand } from '../index.js';
9
+ export default class Serve extends BaseCommand {
10
+ static description: string;
11
+ static examples: string[];
12
+ static flags: {
13
+ datadir: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
14
+ environment: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
15
+ port: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<number, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
16
+ host: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
17
+ 'frontend-sdk-key': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
18
+ 'cors-origin': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string[], import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
19
+ watch: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
20
+ 'allow-non-loopback': import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
21
+ };
22
+ run(): Promise<JsonObj | void>;
23
+ }
@@ -0,0 +1,136 @@
1
+ /**
2
+ * `qfg serve` — Node-native local server that exposes a datadir over the
3
+ * same HTTP protocol the browser SDKs already speak. Designed to close the
4
+ * "browser SDKs can't read a local datadir" gap (epic qfg-38sf, plan
5
+ * project/plans/qfg-serve.md, Option A).
6
+ */
7
+ import { Flags } from '@oclif/core';
8
+ import { BaseCommand } from '../index.js';
9
+ import { resolveDatadirForServe } from '../serve/datadir-discovery.js';
10
+ import { startServer } from '../serve/server.js';
11
+ export default class Serve extends BaseCommand {
12
+ static description = `Serve a local datadir over HTTP to browser/RN SDKs.
13
+
14
+ Reads configs from a local datadir and exposes them at
15
+ \`GET /api/v2/configs/eval-with-context/{base64url(ctx)}\`. Point your
16
+ browser SDK at the resulting URL (\`http://localhost:6580\` by default)
17
+ and the same client code that talks to api-delivery in production will
18
+ work unmodified.
19
+
20
+ Telemetry is intentionally not served — qfg serve has no Quonfig backend
21
+ behind it. Disable client-side telemetry with
22
+ \`collectEvaluationSummaries: false\` (and \`contextUploadMode: "none"\`),
23
+ or point the SDK's \`telemetryUrl\` at a real endpoint.
24
+
25
+ The server is bound to 127.0.0.1 by default; pass --allow-non-loopback
26
+ to confirm a LAN-reachable bind.`;
27
+ static examples = [
28
+ '<%= config.bin %> serve',
29
+ '<%= config.bin %> serve --datadir ./our-config --environment production',
30
+ '<%= config.bin %> serve --port 6581 --frontend-sdk-key PUBLIC_KEY',
31
+ ];
32
+ static flags = {
33
+ datadir: Flags.string({
34
+ description: 'Datadir to serve (defaults to ./our-config, then ./.quonfig, then errors). Honors QUONFIG_DIR.',
35
+ }),
36
+ environment: Flags.string({
37
+ default: 'development',
38
+ description: 'Which environment slug to evaluate. Honors QUONFIG_ENVIRONMENT.',
39
+ }),
40
+ port: Flags.integer({
41
+ default: 6580,
42
+ description: 'TCP port to listen on. Errors on collision; pass --port <n> to retry.',
43
+ }),
44
+ host: Flags.string({
45
+ default: '127.0.0.1',
46
+ description: 'Bind address. Loopback by default; non-loopback requires --allow-non-loopback.',
47
+ }),
48
+ 'frontend-sdk-key': Flags.string({
49
+ description: 'If set, every request must present Authorization: Basic 1:<key>. ' +
50
+ 'If unset, the server is open (matches the "datadir is the source of truth" mental model).',
51
+ }),
52
+ 'cors-origin': Flags.string({
53
+ default: ['*'],
54
+ description: 'Allowed CORS origin (repeatable). Default is *; required when binding to a non-loopback host.',
55
+ multiple: true,
56
+ }),
57
+ watch: Flags.boolean({
58
+ allowNo: true,
59
+ default: true,
60
+ description: 'Reload the envelope when the datadir changes. --no-watch disables.',
61
+ }),
62
+ 'allow-non-loopback': Flags.boolean({
63
+ default: false,
64
+ description: 'Confirm a LAN-reachable bind. Required when --host is not loopback.',
65
+ }),
66
+ };
67
+ async run() {
68
+ const { flags } = await this.parse(Serve);
69
+ const envEnvironment = process.env.QUONFIG_ENVIRONMENT;
70
+ const environment = flags.environment ?? envEnvironment ?? 'development';
71
+ const resolved = resolveDatadirForServe({
72
+ flagDatadir: flags.datadir,
73
+ envDatadir: process.env.QUONFIG_DIR,
74
+ cwd: process.cwd(),
75
+ });
76
+ if (resolved.kind === 'error') {
77
+ return this.err(resolved.message);
78
+ }
79
+ const datadir = resolved.dir;
80
+ if (this.isVerbose) {
81
+ this.verboseLog('Serve', { datadir, environment, port: flags.port, host: flags.host });
82
+ }
83
+ const logger = {
84
+ log: (msg) => this.log(msg),
85
+ warn: (msg) => this.logToStderr(msg),
86
+ };
87
+ let handle;
88
+ try {
89
+ handle = await startServer({
90
+ datadir,
91
+ environment,
92
+ port: flags.port,
93
+ host: flags.host,
94
+ frontendSdkKey: flags['frontend-sdk-key'],
95
+ corsOrigins: flags['cors-origin'],
96
+ watch: flags.watch,
97
+ allowNonLoopback: flags['allow-non-loopback'],
98
+ verbose: this.isVerbose,
99
+ logger,
100
+ });
101
+ }
102
+ catch (error) {
103
+ return this.err(error.message);
104
+ }
105
+ const url = `http://${flags.host}:${handle.port}`;
106
+ this.log(`qfg serve listening on ${url}`);
107
+ this.log(` datadir: ${datadir}`);
108
+ this.log(` environment: ${environment}`);
109
+ if (flags['frontend-sdk-key']) {
110
+ this.log(` auth: required (Authorization: Basic 1:<key>)`);
111
+ }
112
+ else {
113
+ this.log(` auth: none (datadir served openly)`);
114
+ }
115
+ this.log('');
116
+ this.log('Point your browser SDK at the URL above:');
117
+ this.log(` init({ apiUrls: ["${url}"] })`);
118
+ this.log('Press Ctrl-C to stop.');
119
+ // Block until the process is killed. The server is already accepting
120
+ // connections; we just need to keep the event loop alive.
121
+ await new Promise((resolve) => {
122
+ const shutdown = async () => {
123
+ this.log('\nqfg serve shutting down...');
124
+ try {
125
+ await handle.close();
126
+ }
127
+ finally {
128
+ resolve();
129
+ }
130
+ };
131
+ process.once('SIGINT', shutdown);
132
+ process.once('SIGTERM', shutdown);
133
+ });
134
+ return { datadir, environment, url };
135
+ }
136
+ }
package/dist/quonfig.js CHANGED
@@ -19,7 +19,6 @@ export const initQuonfig = async (_ctx, flagsOrDatafile) => {
19
19
  quonfig = new Quonfig({
20
20
  sdkKey,
21
21
  collectEvaluationSummaries: false,
22
- collectLoggerCounts: false,
23
22
  contextUploadMode: 'none',
24
23
  datafile,
25
24
  enableSSE: false,
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Datadir discovery for `qfg serve`.
3
+ *
4
+ * Resolution order (plan §4):
5
+ * 1. --datadir flag
6
+ * 2. QUONFIG_DIR env var
7
+ * 3. ./our-config if present
8
+ * 4. ./.quonfig if present
9
+ * 5. error
10
+ *
11
+ * Kept narrow on purpose: `qfg pull`/`qfg push` use a richer
12
+ * `resolveWorkspaceDir` helper that walks up looking for `quonfig.json` — but
13
+ * `qfg serve` is intentionally cwd-relative (the user said "serve THIS dir")
14
+ * and the walk would surface a confusing path on a misconfigured repo. The
15
+ * default-pair lookup mirrors `qfg pull --dir` defaults documented in the
16
+ * plan.
17
+ */
18
+ export declare const DEFAULT_DATADIR_CANDIDATES: readonly ["our-config", ".quonfig"];
19
+ export declare const NO_DATADIR_ERROR: string;
20
+ export interface ResolveDatadirInput {
21
+ cwd: string;
22
+ envDatadir: string | undefined;
23
+ flagDatadir: string | undefined;
24
+ }
25
+ export type ResolveDatadirResult = {
26
+ kind: 'ok';
27
+ dir: string;
28
+ source: 'flag' | 'env' | 'cwd-default';
29
+ } | {
30
+ kind: 'error';
31
+ message: string;
32
+ };
33
+ export declare const resolveDatadirForServe: (input: ResolveDatadirInput) => ResolveDatadirResult;