@quonfig/cli 0.0.1 → 0.0.4
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 +157 -21
- package/bin/dev.js +5 -9
- package/bin/dev.mjs +6 -0
- package/dist/codegen/zod-introspection.js +13 -4
- package/dist/commands/init.d.ts +13 -0
- package/dist/commands/init.js +83 -0
- package/dist/commands/login.js +27 -6
- package/dist/commands/mcp.js +1 -1
- package/dist/commands/pull.d.ts +15 -0
- package/dist/commands/pull.js +176 -0
- package/dist/commands/serve.js +3 -1
- package/dist/commands/sync.d.ts +18 -0
- package/dist/commands/sync.js +142 -0
- package/dist/commands/whoami.js +4 -1
- package/dist/commands/workspace/bootstrap.d.ts +13 -0
- package/dist/commands/workspace/bootstrap.js +155 -0
- package/dist/init/init-workspace.d.ts +25 -0
- package/dist/init/init-workspace.js +162 -0
- package/dist/init/samples.d.ts +11 -0
- package/dist/init/samples.js +118 -0
- package/dist/init/schema.d.ts +9 -0
- package/dist/init/schema.js +334 -0
- package/dist/init/templates.d.ts +12 -0
- package/dist/init/templates.js +161 -0
- package/dist/util/coerce.js +2 -1
- package/dist/util/get-client.js +6 -44
- package/dist/util/get-valid-token.d.ts +5 -0
- package/dist/util/get-valid-token.js +44 -0
- package/dist/util/git-ops.d.ts +32 -0
- package/dist/util/git-ops.js +164 -0
- package/dist/util/gitea-api.d.ts +11 -0
- package/dist/util/gitea-api.js +45 -0
- package/dist/util/gitea-token-storage.d.ts +8 -0
- package/dist/util/gitea-token-storage.js +47 -0
- package/dist/util/token-storage.d.ts +1 -0
- package/dist/util/token-storage.js +30 -11
- package/dist/verify/validate.d.ts +14 -0
- package/dist/verify/validate.js +224 -19
- package/oclif.manifest.json +298 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ $ npm install -g @quonfig/cli
|
|
|
14
14
|
$ qfg COMMAND
|
|
15
15
|
running command...
|
|
16
16
|
$ qfg (--version)
|
|
17
|
-
@quonfig/cli/0.0.
|
|
17
|
+
@quonfig/cli/0.0.4 linux-x64 node-v24.4.1
|
|
18
18
|
$ qfg --help [COMMAND]
|
|
19
19
|
USAGE
|
|
20
20
|
$ qfg COMMAND
|
|
@@ -31,6 +31,7 @@ USAGE
|
|
|
31
31
|
* [`qfg generate-new-hex-key`](#qfg-generate-new-hex-key)
|
|
32
32
|
* [`qfg get [NAME]`](#qfg-get-name)
|
|
33
33
|
* [`qfg info [NAME]`](#qfg-info-name)
|
|
34
|
+
* [`qfg init [DIRECTORY]`](#qfg-init-directory)
|
|
34
35
|
* [`qfg interactive`](#qfg-interactive)
|
|
35
36
|
* [`qfg list`](#qfg-list)
|
|
36
37
|
* [`qfg login`](#qfg-login)
|
|
@@ -38,12 +39,15 @@ USAGE
|
|
|
38
39
|
* [`qfg mcp`](#qfg-mcp)
|
|
39
40
|
* [`qfg override [NAME]`](#qfg-override-name)
|
|
40
41
|
* [`qfg profile`](#qfg-profile)
|
|
42
|
+
* [`qfg pull`](#qfg-pull)
|
|
41
43
|
* [`qfg schema NAME`](#qfg-schema-name)
|
|
42
44
|
* [`qfg serve DATA-FILE`](#qfg-serve-data-file)
|
|
43
45
|
* [`qfg set-default [NAME]`](#qfg-set-default-name)
|
|
46
|
+
* [`qfg sync`](#qfg-sync)
|
|
44
47
|
* [`qfg verify [PATH]`](#qfg-verify-path)
|
|
45
48
|
* [`qfg whoami`](#qfg-whoami)
|
|
46
49
|
* [`qfg workspace`](#qfg-workspace)
|
|
50
|
+
* [`qfg workspace bootstrap`](#qfg-workspace-bootstrap)
|
|
47
51
|
|
|
48
52
|
## `qfg create NAME`
|
|
49
53
|
|
|
@@ -92,7 +96,7 @@ EXAMPLES
|
|
|
92
96
|
$ qfg create my.new.string --type json --value="{\"key\": \"value\"}"
|
|
93
97
|
```
|
|
94
98
|
|
|
95
|
-
_See code: [src/commands/create.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
99
|
+
_See code: [src/commands/create.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/create.ts)_
|
|
96
100
|
|
|
97
101
|
## `qfg download`
|
|
98
102
|
|
|
@@ -125,7 +129,7 @@ EXAMPLES
|
|
|
125
129
|
$ qfg download --environment=test --sdk-key=YOUR_SDK_KEY
|
|
126
130
|
```
|
|
127
131
|
|
|
128
|
-
_See code: [src/commands/download.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
132
|
+
_See code: [src/commands/download.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/download.ts)_
|
|
129
133
|
|
|
130
134
|
## `qfg generate`
|
|
131
135
|
|
|
@@ -195,7 +199,7 @@ EXAMPLES
|
|
|
195
199
|
$ qfg generate --targets node-ts -o ./dist # combine with targets
|
|
196
200
|
```
|
|
197
201
|
|
|
198
|
-
_See code: [src/commands/generate.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
202
|
+
_See code: [src/commands/generate.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/generate.ts)_
|
|
199
203
|
|
|
200
204
|
## `qfg generate-new-hex-key`
|
|
201
205
|
|
|
@@ -218,7 +222,7 @@ EXAMPLES
|
|
|
218
222
|
$ qfg generate-new-hex-key
|
|
219
223
|
```
|
|
220
224
|
|
|
221
|
-
_See code: [src/commands/generate-new-hex-key.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
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)_
|
|
222
226
|
|
|
223
227
|
## `qfg get [NAME]`
|
|
224
228
|
|
|
@@ -250,7 +254,7 @@ EXAMPLES
|
|
|
250
254
|
$ qfg get my.config.name --environment=production
|
|
251
255
|
```
|
|
252
256
|
|
|
253
|
-
_See code: [src/commands/get.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
257
|
+
_See code: [src/commands/get.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/get.ts)_
|
|
254
258
|
|
|
255
259
|
## `qfg info [NAME]`
|
|
256
260
|
|
|
@@ -280,7 +284,45 @@ EXAMPLES
|
|
|
280
284
|
$ qfg info my.config.name
|
|
281
285
|
```
|
|
282
286
|
|
|
283
|
-
_See code: [src/commands/info.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
287
|
+
_See code: [src/commands/info.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/info.ts)_
|
|
288
|
+
|
|
289
|
+
## `qfg init [DIRECTORY]`
|
|
290
|
+
|
|
291
|
+
Initialize or update a Quonfig workspace
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
USAGE
|
|
295
|
+
$ qfg init [DIRECTORY] [--json] [--interactive] [--no-color] [--verbose] [--dry-run] [--samples]
|
|
296
|
+
|
|
297
|
+
ARGUMENTS
|
|
298
|
+
DIRECTORY [default: .] Target directory (default: current directory)
|
|
299
|
+
|
|
300
|
+
FLAGS
|
|
301
|
+
--dry-run Show what would be done without writing anything
|
|
302
|
+
--[no-]samples Include sample configs (default: yes on first init, no on update)
|
|
303
|
+
|
|
304
|
+
GLOBAL FLAGS
|
|
305
|
+
--[no-]interactive Force interactive mode
|
|
306
|
+
--json Format output as json.
|
|
307
|
+
--no-color Do not colorize output
|
|
308
|
+
--verbose Verbose output
|
|
309
|
+
|
|
310
|
+
DESCRIPTION
|
|
311
|
+
Initialize or update a Quonfig workspace
|
|
312
|
+
|
|
313
|
+
EXAMPLES
|
|
314
|
+
$ qfg init
|
|
315
|
+
|
|
316
|
+
$ qfg init ./my-workspace
|
|
317
|
+
|
|
318
|
+
$ qfg init --no-samples
|
|
319
|
+
|
|
320
|
+
$ qfg init --samples
|
|
321
|
+
|
|
322
|
+
$ qfg init --dry-run
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
_See code: [src/commands/init.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/init.ts)_
|
|
284
326
|
|
|
285
327
|
## `qfg interactive`
|
|
286
328
|
|
|
@@ -298,7 +340,7 @@ EXAMPLES
|
|
|
298
340
|
$ qfg
|
|
299
341
|
```
|
|
300
342
|
|
|
301
|
-
_See code: [src/commands/interactive.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
343
|
+
_See code: [src/commands/interactive.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/interactive.ts)_
|
|
302
344
|
|
|
303
345
|
## `qfg list`
|
|
304
346
|
|
|
@@ -335,7 +377,7 @@ EXAMPLES
|
|
|
335
377
|
$ qfg list --feature-flags
|
|
336
378
|
```
|
|
337
379
|
|
|
338
|
-
_See code: [src/commands/list.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
380
|
+
_See code: [src/commands/list.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/list.ts)_
|
|
339
381
|
|
|
340
382
|
## `qfg login`
|
|
341
383
|
|
|
@@ -363,7 +405,7 @@ EXAMPLES
|
|
|
363
405
|
$ qfg login --profile myprofile
|
|
364
406
|
```
|
|
365
407
|
|
|
366
|
-
_See code: [src/commands/login.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
408
|
+
_See code: [src/commands/login.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/login.ts)_
|
|
367
409
|
|
|
368
410
|
## `qfg logout`
|
|
369
411
|
|
|
@@ -386,7 +428,7 @@ EXAMPLES
|
|
|
386
428
|
$ qfg logout
|
|
387
429
|
```
|
|
388
430
|
|
|
389
|
-
_See code: [src/commands/logout.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
431
|
+
_See code: [src/commands/logout.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/logout.ts)_
|
|
390
432
|
|
|
391
433
|
## `qfg mcp`
|
|
392
434
|
|
|
@@ -416,10 +458,10 @@ EXAMPLES
|
|
|
416
458
|
|
|
417
459
|
$ qfg mcp --editor cursor
|
|
418
460
|
|
|
419
|
-
$ qfg mcp --url http://local-app.
|
|
461
|
+
$ qfg mcp --url http://local-app.quonfig-staging.com:3003/api/v1/mcp
|
|
420
462
|
```
|
|
421
463
|
|
|
422
|
-
_See code: [src/commands/mcp.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
464
|
+
_See code: [src/commands/mcp.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/mcp.ts)_
|
|
423
465
|
|
|
424
466
|
## `qfg override [NAME]`
|
|
425
467
|
|
|
@@ -458,7 +500,7 @@ EXAMPLES
|
|
|
458
500
|
$ qfg override my.double.config --value=3.14159
|
|
459
501
|
```
|
|
460
502
|
|
|
461
|
-
_See code: [src/commands/override.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
503
|
+
_See code: [src/commands/override.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/override.ts)_
|
|
462
504
|
|
|
463
505
|
## `qfg profile`
|
|
464
506
|
|
|
@@ -481,7 +523,36 @@ EXAMPLES
|
|
|
481
523
|
$ qfg profile
|
|
482
524
|
```
|
|
483
525
|
|
|
484
|
-
_See code: [src/commands/profile.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
526
|
+
_See code: [src/commands/profile.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/profile.ts)_
|
|
527
|
+
|
|
528
|
+
## `qfg pull`
|
|
529
|
+
|
|
530
|
+
Clone or update a local directory from the workspace Gitea repo
|
|
531
|
+
|
|
532
|
+
```
|
|
533
|
+
USAGE
|
|
534
|
+
$ qfg pull [--json] [--interactive] [--no-color] [--verbose] [--dir <value>] [--workspace <value>]
|
|
535
|
+
|
|
536
|
+
FLAGS
|
|
537
|
+
--dir=<value> Local directory to clone/update (defaults to QUONFIG_DIR env var)
|
|
538
|
+
--workspace=<value> Workspace ID (defaults to active profile)
|
|
539
|
+
|
|
540
|
+
GLOBAL FLAGS
|
|
541
|
+
--[no-]interactive Force interactive mode
|
|
542
|
+
--json Format output as json.
|
|
543
|
+
--no-color Do not colorize output
|
|
544
|
+
--verbose Verbose output
|
|
545
|
+
|
|
546
|
+
DESCRIPTION
|
|
547
|
+
Clone or update a local directory from the workspace Gitea repo
|
|
548
|
+
|
|
549
|
+
EXAMPLES
|
|
550
|
+
$ qfg pull --dir ./our-config
|
|
551
|
+
|
|
552
|
+
$ qfg pull # uses QUONFIG_DIR env var
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
_See code: [src/commands/pull.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/pull.ts)_
|
|
485
556
|
|
|
486
557
|
## `qfg schema NAME`
|
|
487
558
|
|
|
@@ -519,7 +590,7 @@ EXAMPLES
|
|
|
519
590
|
$ qfg schema my-schema --set-json-schema=@schemas/my-schema.json --protected
|
|
520
591
|
```
|
|
521
592
|
|
|
522
|
-
_See code: [src/commands/schema.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
593
|
+
_See code: [src/commands/schema.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/schema.ts)_
|
|
523
594
|
|
|
524
595
|
## `qfg serve DATA-FILE`
|
|
525
596
|
|
|
@@ -555,7 +626,7 @@ EXAMPLES
|
|
|
555
626
|
$ qfg serve ./quonfig.test.588.config.json --port=3099
|
|
556
627
|
```
|
|
557
628
|
|
|
558
|
-
_See code: [src/commands/serve.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
629
|
+
_See code: [src/commands/serve.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/serve.ts)_
|
|
559
630
|
|
|
560
631
|
## `qfg set-default [NAME]`
|
|
561
632
|
|
|
@@ -599,7 +670,39 @@ EXAMPLES
|
|
|
599
670
|
$ qfg set-default my.config.name --env-var=MY_ENV_VAR_NAME --environment=production
|
|
600
671
|
```
|
|
601
672
|
|
|
602
|
-
_See code: [src/commands/set-default.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
673
|
+
_See code: [src/commands/set-default.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/set-default.ts)_
|
|
674
|
+
|
|
675
|
+
## `qfg sync`
|
|
676
|
+
|
|
677
|
+
Continuously poll for workspace config updates and apply them locally
|
|
678
|
+
|
|
679
|
+
```
|
|
680
|
+
USAGE
|
|
681
|
+
$ qfg sync --watch [--json] [--interactive] [--no-color] [--verbose] [--dir <value>] [--interval <value>]
|
|
682
|
+
|
|
683
|
+
FLAGS
|
|
684
|
+
--dir=<value> Local directory to sync (defaults to QUONFIG_DIR env var)
|
|
685
|
+
--interval=<value> [default: 60] Poll interval in seconds
|
|
686
|
+
--watch (required) Run as a continuous polling daemon (required)
|
|
687
|
+
|
|
688
|
+
GLOBAL FLAGS
|
|
689
|
+
--[no-]interactive Force interactive mode
|
|
690
|
+
--json Format output as json.
|
|
691
|
+
--no-color Do not colorize output
|
|
692
|
+
--verbose Verbose output
|
|
693
|
+
|
|
694
|
+
DESCRIPTION
|
|
695
|
+
Continuously poll for workspace config updates and apply them locally
|
|
696
|
+
|
|
697
|
+
EXAMPLES
|
|
698
|
+
$ qfg sync --watch
|
|
699
|
+
|
|
700
|
+
$ qfg sync --watch --interval 10
|
|
701
|
+
|
|
702
|
+
$ qfg sync --watch --dir ./our-config --interval 30
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
_See code: [src/commands/sync.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/sync.ts)_
|
|
603
706
|
|
|
604
707
|
## `qfg verify [PATH]`
|
|
605
708
|
|
|
@@ -632,7 +735,7 @@ EXAMPLES
|
|
|
632
735
|
$ qfg verify --json
|
|
633
736
|
```
|
|
634
737
|
|
|
635
|
-
_See code: [src/commands/verify.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
738
|
+
_See code: [src/commands/verify.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/verify.ts)_
|
|
636
739
|
|
|
637
740
|
## `qfg whoami`
|
|
638
741
|
|
|
@@ -655,7 +758,7 @@ EXAMPLES
|
|
|
655
758
|
$ qfg whoami
|
|
656
759
|
```
|
|
657
760
|
|
|
658
|
-
_See code: [src/commands/whoami.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
761
|
+
_See code: [src/commands/whoami.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/whoami.ts)_
|
|
659
762
|
|
|
660
763
|
## `qfg workspace`
|
|
661
764
|
|
|
@@ -678,7 +781,40 @@ EXAMPLES
|
|
|
678
781
|
$ qfg workspace
|
|
679
782
|
```
|
|
680
783
|
|
|
681
|
-
_See code: [src/commands/workspace.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
784
|
+
_See code: [src/commands/workspace.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/workspace.ts)_
|
|
785
|
+
|
|
786
|
+
## `qfg workspace bootstrap`
|
|
787
|
+
|
|
788
|
+
Push a local git repo to Gitea as this workspace's config repository
|
|
789
|
+
|
|
790
|
+
```
|
|
791
|
+
USAGE
|
|
792
|
+
$ qfg workspace bootstrap [--json] [--interactive] [--no-color] [--verbose] [--dir <value>] [--force]
|
|
793
|
+
[--skip-validate]
|
|
794
|
+
|
|
795
|
+
FLAGS
|
|
796
|
+
--dir=<value> Local directory to push (defaults to current directory)
|
|
797
|
+
--force Force push even if remote already has commits
|
|
798
|
+
--skip-validate Skip config validation before pushing
|
|
799
|
+
|
|
800
|
+
GLOBAL FLAGS
|
|
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
|
+
Push a local git repo to Gitea as this workspace's config repository
|
|
808
|
+
|
|
809
|
+
EXAMPLES
|
|
810
|
+
$ qfg workspace bootstrap --dir ./our-config
|
|
811
|
+
|
|
812
|
+
$ qfg workspace bootstrap --dir ./launch-migrator/output
|
|
813
|
+
|
|
814
|
+
$ qfg workspace bootstrap --dir ./our-config --skip-validate
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
_See code: [src/commands/workspace/bootstrap.ts](https://github.com/quonfig/cli/blob/v0.0.4/src/commands/workspace/bootstrap.ts)_
|
|
682
818
|
<!-- commandsstop -->
|
|
683
819
|
|
|
684
820
|
## Local Development
|
package/bin/dev.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
await execute({development: true, dir: import.meta.url})
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
await main()
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Run dev CLI from any directory — ensures ts-node resolves from cli's node_modules
|
|
3
|
+
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
4
|
+
export TS_NODE_PROJECT="$DIR/tsconfig.json"
|
|
5
|
+
exec node --loader "$DIR/node_modules/ts-node/esm.mjs" --no-warnings=ExperimentalWarning "$DIR/bin/dev.mjs" "$@"
|
package/bin/dev.mjs
ADDED
|
@@ -183,18 +183,27 @@ export function getMetaDescription(schema) {
|
|
|
183
183
|
if (!meta || Object.keys(meta).length === 0) {
|
|
184
184
|
return undefined;
|
|
185
185
|
}
|
|
186
|
-
// If meta only has a description key, return just the description
|
|
187
186
|
const keys = Object.keys(meta);
|
|
188
|
-
|
|
189
|
-
|
|
187
|
+
const standardKeys = new Set(['title', 'description']);
|
|
188
|
+
const hasExtraKeys = keys.some((k) => !standardKeys.has(k));
|
|
189
|
+
// If meta has non-standard keys (e.g. id, required, deprecated),
|
|
190
|
+
// return JSON representation of the entire meta object so all metadata is preserved
|
|
191
|
+
if (hasExtraKeys) {
|
|
192
|
+
try {
|
|
193
|
+
return JSON.stringify(meta, null, 2);
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
// If JSON serialization fails, fall through
|
|
197
|
+
}
|
|
190
198
|
}
|
|
199
|
+
// For standard keys only (title, description), prefer description then title
|
|
191
200
|
if (typeof meta.description === 'string') {
|
|
192
201
|
return meta.description;
|
|
193
202
|
}
|
|
194
203
|
if (typeof meta.title === 'string') {
|
|
195
204
|
return meta.title;
|
|
196
205
|
}
|
|
197
|
-
//
|
|
206
|
+
// Fallback: return JSON representation of the entire meta object
|
|
198
207
|
try {
|
|
199
208
|
return JSON.stringify(meta, null, 2);
|
|
200
209
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseCommand } from '../index.js';
|
|
2
|
+
export default class Init extends BaseCommand {
|
|
3
|
+
static args: {
|
|
4
|
+
directory: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
|
|
5
|
+
};
|
|
6
|
+
static description: string;
|
|
7
|
+
static examples: string[];
|
|
8
|
+
static flags: {
|
|
9
|
+
'dry-run': import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
10
|
+
samples: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<object>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import { BaseCommand } from '../index.js';
|
|
3
|
+
import { executeInit, planInit } from '../init/init-workspace.js';
|
|
4
|
+
export default class Init extends BaseCommand {
|
|
5
|
+
static args = {
|
|
6
|
+
directory: Args.string({
|
|
7
|
+
default: '.',
|
|
8
|
+
description: 'Target directory (default: current directory)',
|
|
9
|
+
}),
|
|
10
|
+
};
|
|
11
|
+
static description = 'Initialize or update a Quonfig workspace';
|
|
12
|
+
static examples = [
|
|
13
|
+
'<%= config.bin %> init',
|
|
14
|
+
'<%= config.bin %> init ./my-workspace',
|
|
15
|
+
'<%= config.bin %> init --no-samples',
|
|
16
|
+
'<%= config.bin %> init --samples',
|
|
17
|
+
'<%= config.bin %> init --dry-run',
|
|
18
|
+
];
|
|
19
|
+
static flags = {
|
|
20
|
+
'dry-run': Flags.boolean({
|
|
21
|
+
default: false,
|
|
22
|
+
description: 'Show what would be done without writing anything',
|
|
23
|
+
}),
|
|
24
|
+
samples: Flags.boolean({
|
|
25
|
+
allowNo: true,
|
|
26
|
+
description: 'Include sample configs (default: yes on first init, no on update)',
|
|
27
|
+
}),
|
|
28
|
+
};
|
|
29
|
+
async run() {
|
|
30
|
+
const { args, flags } = await this.parse(Init);
|
|
31
|
+
const dir = args.directory;
|
|
32
|
+
const plan = planInit({
|
|
33
|
+
dir,
|
|
34
|
+
dryRun: flags['dry-run'],
|
|
35
|
+
samples: flags.samples,
|
|
36
|
+
});
|
|
37
|
+
const mode = plan.isFirstTime ? 'Initializing' : 'Updating';
|
|
38
|
+
const writeActions = plan.actions.filter((a) => a.kind !== 'skip-file' && a.kind !== 'skip-hook');
|
|
39
|
+
const skipActions = plan.actions.filter((a) => a.kind === 'skip-file' || a.kind === 'skip-hook');
|
|
40
|
+
if (flags['dry-run']) {
|
|
41
|
+
this.log(`${mode} workspace (dry run)\n`);
|
|
42
|
+
if (writeActions.length > 0) {
|
|
43
|
+
this.log('Would perform:');
|
|
44
|
+
for (const action of writeActions) {
|
|
45
|
+
this.log(` + ${action.description}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (skipActions.length > 0) {
|
|
49
|
+
this.log('\nSkipped:');
|
|
50
|
+
for (const action of skipActions) {
|
|
51
|
+
this.log(` - ${action.description}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (writeActions.length === 0) {
|
|
55
|
+
this.log(' Nothing to do.');
|
|
56
|
+
}
|
|
57
|
+
if (this.jsonEnabled()) {
|
|
58
|
+
return { actions: plan.actions, dryRun: true, isFirstTime: plan.isFirstTime, samplesIncluded: plan.samplesIncluded };
|
|
59
|
+
}
|
|
60
|
+
return plan;
|
|
61
|
+
}
|
|
62
|
+
// Execute for real
|
|
63
|
+
executeInit(plan, dir);
|
|
64
|
+
this.log(`${mode} workspace: ${dir === '.' ? process.cwd() : dir}\n`);
|
|
65
|
+
for (const action of writeActions) {
|
|
66
|
+
this.log(` + ${action.description}`);
|
|
67
|
+
}
|
|
68
|
+
for (const action of skipActions) {
|
|
69
|
+
this.log(` - ${action.description}`);
|
|
70
|
+
}
|
|
71
|
+
if (!plan.samplesIncluded && plan.isFirstTime) {
|
|
72
|
+
this.log('\nSample data skipped. Run `qfg init --samples` to add examples.');
|
|
73
|
+
}
|
|
74
|
+
else if (!plan.isFirstTime && !plan.samplesIncluded) {
|
|
75
|
+
this.log('\nDocs updated. Run `qfg init --samples` to add example configs.');
|
|
76
|
+
}
|
|
77
|
+
this.log('\nRun `qfg verify` to validate the workspace.');
|
|
78
|
+
if (this.jsonEnabled()) {
|
|
79
|
+
return { actions: plan.actions, dryRun: false, isFirstTime: plan.isFirstTime, samplesIncluded: plan.samplesIncluded };
|
|
80
|
+
}
|
|
81
|
+
return plan;
|
|
82
|
+
}
|
|
83
|
+
}
|
package/dist/commands/login.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Flags } from '@oclif/core';
|
|
2
|
+
import { select } from '@inquirer/prompts';
|
|
2
3
|
import { BaseCommand } from '../index.js';
|
|
3
4
|
import { decodeJWT, pollForToken, requestDeviceCode } from '../util/oauth-client.js';
|
|
4
5
|
import { getApiUrl } from '../util/domain-urls.js';
|
|
@@ -53,6 +54,8 @@ export default class Login extends BaseCommand {
|
|
|
53
54
|
// Resolve org_id → workspace UUID via the API
|
|
54
55
|
let workspaceId;
|
|
55
56
|
let workspaceName;
|
|
57
|
+
let workspaceSlug;
|
|
58
|
+
let organizationName;
|
|
56
59
|
try {
|
|
57
60
|
const apiUrl = getApiUrl();
|
|
58
61
|
this.verboseLog('Resolving workspace...', { apiUrl, orgId });
|
|
@@ -66,14 +69,28 @@ export default class Login extends BaseCommand {
|
|
|
66
69
|
});
|
|
67
70
|
if (res.ok) {
|
|
68
71
|
const body = await res.json();
|
|
69
|
-
const
|
|
70
|
-
const
|
|
71
|
-
?
|
|
72
|
-
:
|
|
72
|
+
const allWorkspaces = (body.json ?? body);
|
|
73
|
+
const orgWorkspaces = Array.isArray(allWorkspaces)
|
|
74
|
+
? allWorkspaces.filter((w) => w.workosOrgId === orgId)
|
|
75
|
+
: [];
|
|
76
|
+
const candidates = orgWorkspaces.length > 0 ? orgWorkspaces : (Array.isArray(allWorkspaces) ? allWorkspaces : []);
|
|
77
|
+
let match;
|
|
78
|
+
if (candidates.length === 1) {
|
|
79
|
+
match = candidates[0];
|
|
80
|
+
}
|
|
81
|
+
else if (candidates.length > 1) {
|
|
82
|
+
const chosen = await select({
|
|
83
|
+
choices: candidates.map((w) => ({ name: w.workspaceSlug, value: w.workspaceId })),
|
|
84
|
+
message: 'Select workspace:',
|
|
85
|
+
});
|
|
86
|
+
match = candidates.find((w) => w.workspaceId === chosen);
|
|
87
|
+
}
|
|
73
88
|
if (match) {
|
|
74
89
|
workspaceId = match.workspaceId;
|
|
75
|
-
workspaceName = match.
|
|
76
|
-
|
|
90
|
+
workspaceName = match.workspaceSlug;
|
|
91
|
+
workspaceSlug = match.workspaceSlug;
|
|
92
|
+
organizationName = match.organizationName;
|
|
93
|
+
this.verboseLog('Resolved workspace', { workspaceId, workspaceName, workspaceSlug, organizationName });
|
|
77
94
|
}
|
|
78
95
|
}
|
|
79
96
|
else {
|
|
@@ -95,6 +112,7 @@ export default class Login extends BaseCommand {
|
|
|
95
112
|
[profileName]: {
|
|
96
113
|
workspace: workspaceId || orgId || 'unknown',
|
|
97
114
|
workspaceName: workspaceName || (orgId ? `org:${orgId}` : undefined),
|
|
115
|
+
workspaceSlug,
|
|
98
116
|
},
|
|
99
117
|
},
|
|
100
118
|
});
|
|
@@ -108,6 +126,9 @@ export default class Login extends BaseCommand {
|
|
|
108
126
|
}
|
|
109
127
|
if (workspaceName) {
|
|
110
128
|
this.log(`Workspace: ${workspaceName} (${workspaceId})`);
|
|
129
|
+
if (organizationName) {
|
|
130
|
+
this.log(`Organization: ${organizationName}`);
|
|
131
|
+
}
|
|
111
132
|
}
|
|
112
133
|
else if (orgId) {
|
|
113
134
|
this.log(`Organization: ${orgId}`);
|
package/dist/commands/mcp.js
CHANGED
|
@@ -12,7 +12,7 @@ export default class Mcp extends BaseCommand {
|
|
|
12
12
|
static examples = [
|
|
13
13
|
'<%= config.bin %> <%= command.id %>',
|
|
14
14
|
'<%= config.bin %> <%= command.id %> --editor cursor',
|
|
15
|
-
'<%= config.bin %> <%= command.id %> --url http://local-app.
|
|
15
|
+
'<%= config.bin %> <%= command.id %> --url http://local-app.quonfig-staging.com:3003/api/v1/mcp',
|
|
16
16
|
];
|
|
17
17
|
static flags = {
|
|
18
18
|
...BaseCommand.baseFlags,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { JsonObj } from '../result.js';
|
|
2
|
+
import { BaseCommand } from '../index.js';
|
|
3
|
+
export default class Pull extends BaseCommand {
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {
|
|
7
|
+
dir: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
8
|
+
workspace: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
9
|
+
};
|
|
10
|
+
run(): Promise<JsonObj | void>;
|
|
11
|
+
private resolveRepoUrl;
|
|
12
|
+
private refreshAndGetUrl;
|
|
13
|
+
private looksLike401;
|
|
14
|
+
private maybeWriteQuonfigDir;
|
|
15
|
+
}
|