kaven-cli 0.4.0 → 0.4.1-alpha.0

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.
@@ -3,1024 +3,159 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ALL_CAPABILITIES = void 0;
7
- exports.generateSeedFile = generateSeedFile;
8
6
  exports.configFeatures = configFeatures;
9
7
  const chalk_1 = __importDefault(require("chalk"));
10
8
  const fs_extra_1 = __importDefault(require("fs-extra"));
11
9
  const path_1 = __importDefault(require("path"));
12
- // ---------------------------------------------------------------------------
13
- // Capability catalog (63 capabilities, 5 categories)
14
- // Mirrors packages/database/prisma/seeds/capabilities.seed.ts in kaven-framework
15
- // Support: 14 | DevOps: 15 | Finance: 12 | Marketing: 10 | Management: 12
16
- // ---------------------------------------------------------------------------
17
- exports.ALL_CAPABILITIES = [
18
- // ===========================
19
- // SUPPORT (14 capabilities)
20
- // ===========================
21
- {
22
- code: "tickets.read",
23
- resource: "tickets",
24
- action: "read",
25
- description: "View support tickets",
26
- category: "Support",
27
- sensitivity: "NORMAL",
28
- scope: "SPACE",
29
- },
30
- {
31
- code: "tickets.create",
32
- resource: "tickets",
33
- action: "create",
34
- description: "Create new tickets",
35
- category: "Support",
36
- sensitivity: "NORMAL",
37
- scope: "SPACE",
38
- },
39
- {
40
- code: "tickets.update",
41
- resource: "tickets",
42
- action: "update",
43
- description: "Update existing tickets",
44
- category: "Support",
45
- sensitivity: "NORMAL",
46
- scope: "ASSIGNED",
47
- },
48
- {
49
- code: "tickets.delete",
50
- resource: "tickets",
51
- action: "delete",
52
- description: "Delete tickets",
53
- category: "Support",
54
- sensitivity: "SENSITIVE",
55
- scope: "SPACE",
56
- requiresApproval: true,
57
- },
58
- {
59
- code: "tickets.assign",
60
- resource: "tickets",
61
- action: "assign",
62
- description: "Assign tickets to agents",
63
- category: "Support",
64
- sensitivity: "NORMAL",
65
- scope: "SPACE",
66
- },
67
- {
68
- code: "tickets.close",
69
- resource: "tickets",
70
- action: "close",
71
- description: "Close resolved tickets",
72
- category: "Support",
73
- sensitivity: "NORMAL",
74
- scope: "ASSIGNED",
75
- },
76
- {
77
- code: "tickets.reopen",
78
- resource: "tickets",
79
- action: "reopen",
80
- description: "Reopen closed tickets",
81
- category: "Support",
82
- sensitivity: "NORMAL",
83
- scope: "SPACE",
84
- },
85
- {
86
- code: "tickets.export",
87
- resource: "tickets",
88
- action: "export",
89
- description: "Export ticket data",
90
- category: "Support",
91
- sensitivity: "SENSITIVE",
92
- scope: "SPACE",
93
- },
94
- {
95
- code: "customers.read",
96
- resource: "customers",
97
- action: "read",
98
- description: "View customer data",
99
- category: "Support",
100
- sensitivity: "SENSITIVE",
101
- scope: "TENANT",
102
- },
103
- {
104
- code: "customers.update",
105
- resource: "customers",
106
- action: "update",
107
- description: "Update customer data",
108
- category: "Support",
109
- sensitivity: "SENSITIVE",
110
- scope: "TENANT",
111
- },
112
- {
113
- code: "kb.read",
114
- resource: "kb",
115
- action: "read",
116
- description: "View knowledge base",
117
- category: "Support",
118
- sensitivity: "NORMAL",
119
- scope: "GLOBAL",
120
- },
121
- {
122
- code: "kb.manage",
123
- resource: "kb",
124
- action: "manage",
125
- description: "Manage knowledge base articles",
126
- category: "Support",
127
- sensitivity: "NORMAL",
128
- scope: "SPACE",
129
- },
130
- {
131
- code: "auth.2fa_reset.request",
132
- resource: "auth",
133
- action: "2fa_reset_request",
134
- description: "Request 2FA reset for a user",
135
- category: "Support",
136
- sensitivity: "HIGHLY_SENSITIVE",
137
- scope: "TENANT",
138
- },
139
- {
140
- code: "auth.2fa_reset.execute",
141
- resource: "auth",
142
- action: "2fa_reset_execute",
143
- description: "Execute 2FA reset for a user",
144
- category: "Support",
145
- sensitivity: "CRITICAL",
146
- scope: "TENANT",
147
- requiresMFA: true,
148
- requiresApproval: true,
149
- },
150
- // ===========================
151
- // DEVOPS (15 capabilities)
152
- // ===========================
153
- {
154
- code: "servers.read",
155
- resource: "servers",
156
- action: "read",
157
- description: "View server information",
158
- category: "DevOps",
159
- sensitivity: "SENSITIVE",
160
- scope: "GLOBAL",
161
- },
162
- {
163
- code: "servers.manage",
164
- resource: "servers",
165
- action: "manage",
166
- description: "Manage server configurations",
167
- category: "DevOps",
168
- sensitivity: "CRITICAL",
169
- scope: "GLOBAL",
170
- requiresMFA: true,
171
- requiresApproval: true,
172
- },
173
- {
174
- code: "deployments.read",
175
- resource: "deployments",
176
- action: "read",
177
- description: "View deployment history",
178
- category: "DevOps",
179
- sensitivity: "NORMAL",
180
- scope: "GLOBAL",
181
- },
182
- {
183
- code: "deployments.create",
184
- resource: "deployments",
185
- action: "create",
186
- description: "Create new deployments",
187
- category: "DevOps",
188
- sensitivity: "CRITICAL",
189
- scope: "GLOBAL",
190
- requiresMFA: true,
191
- },
192
- {
193
- code: "deployments.rollback",
194
- resource: "deployments",
195
- action: "rollback",
196
- description: "Rollback deployments",
197
- category: "DevOps",
198
- sensitivity: "CRITICAL",
199
- scope: "GLOBAL",
200
- requiresMFA: true,
201
- requiresApproval: true,
202
- },
203
- {
204
- code: "logs.read",
205
- resource: "logs",
206
- action: "read",
207
- description: "View system logs",
208
- category: "DevOps",
209
- sensitivity: "SENSITIVE",
210
- scope: "GLOBAL",
211
- },
212
- {
213
- code: "logs.export",
214
- resource: "logs",
215
- action: "export",
216
- description: "Export system logs",
217
- category: "DevOps",
218
- sensitivity: "HIGHLY_SENSITIVE",
219
- scope: "GLOBAL",
220
- requiresApproval: true,
221
- },
222
- {
223
- code: "monitoring.read",
224
- resource: "monitoring",
225
- action: "read",
226
- description: "View monitoring metrics",
227
- category: "DevOps",
228
- sensitivity: "NORMAL",
229
- scope: "GLOBAL",
230
- },
231
- {
232
- code: "monitoring.manage",
233
- resource: "monitoring",
234
- action: "manage",
235
- description: "Manage alerts and dashboards",
236
- category: "DevOps",
237
- sensitivity: "SENSITIVE",
238
- scope: "GLOBAL",
239
- },
240
- {
241
- code: "database.read",
242
- resource: "database",
243
- action: "read",
244
- description: "View database information",
245
- category: "DevOps",
246
- sensitivity: "HIGHLY_SENSITIVE",
247
- scope: "GLOBAL",
248
- requiresMFA: true,
249
- },
250
- {
251
- code: "database.backup",
252
- resource: "database",
253
- action: "backup",
254
- description: "Create database backups",
255
- category: "DevOps",
256
- sensitivity: "CRITICAL",
257
- scope: "GLOBAL",
258
- requiresMFA: true,
259
- },
260
- {
261
- code: "database.restore",
262
- resource: "database",
263
- action: "restore",
264
- description: "Restore database backups",
265
- category: "DevOps",
266
- sensitivity: "CRITICAL",
267
- scope: "GLOBAL",
268
- requiresMFA: true,
269
- requiresApproval: true,
270
- },
271
- {
272
- code: "secrets.read",
273
- resource: "secrets",
274
- action: "read",
275
- description: "View secrets and environment variables",
276
- category: "DevOps",
277
- sensitivity: "CRITICAL",
278
- scope: "GLOBAL",
279
- requiresMFA: true,
280
- },
281
- {
282
- code: "secrets.manage",
283
- resource: "secrets",
284
- action: "manage",
285
- description: "Manage secrets and environment variables",
286
- category: "DevOps",
287
- sensitivity: "CRITICAL",
288
- scope: "GLOBAL",
289
- requiresMFA: true,
290
- requiresApproval: true,
291
- },
292
- {
293
- code: "incidents.manage",
294
- resource: "incidents",
295
- action: "manage",
296
- description: "Manage production incidents",
297
- category: "DevOps",
298
- sensitivity: "SENSITIVE",
299
- scope: "GLOBAL",
300
- },
301
- // ===========================
302
- // FINANCE (12 capabilities)
303
- // ===========================
304
- {
305
- code: "invoices.read",
306
- resource: "invoices",
307
- action: "read",
308
- description: "View invoices",
309
- category: "Finance",
310
- sensitivity: "SENSITIVE",
311
- scope: "TENANT",
312
- },
313
- {
314
- code: "invoices.create",
315
- resource: "invoices",
316
- action: "create",
317
- description: "Create new invoices",
318
- category: "Finance",
319
- sensitivity: "SENSITIVE",
320
- scope: "TENANT",
321
- },
322
- {
323
- code: "invoices.update",
324
- resource: "invoices",
325
- action: "update",
326
- description: "Update existing invoices",
327
- category: "Finance",
328
- sensitivity: "SENSITIVE",
329
- scope: "TENANT",
330
- requiresApproval: true,
331
- },
332
- {
333
- code: "invoices.delete",
334
- resource: "invoices",
335
- action: "delete",
336
- description: "Delete invoices",
337
- category: "Finance",
338
- sensitivity: "HIGHLY_SENSITIVE",
339
- scope: "TENANT",
340
- requiresMFA: true,
341
- requiresApproval: true,
342
- },
343
- {
344
- code: "payments.read",
345
- resource: "payments",
346
- action: "read",
347
- description: "View payments",
348
- category: "Finance",
349
- sensitivity: "SENSITIVE",
350
- scope: "TENANT",
351
- },
352
- {
353
- code: "payments.process",
354
- resource: "payments",
355
- action: "process",
356
- description: "Process payments",
357
- category: "Finance",
358
- sensitivity: "HIGHLY_SENSITIVE",
359
- scope: "TENANT",
360
- requiresMFA: true,
361
- },
362
- {
363
- code: "refunds.create",
364
- resource: "refunds",
365
- action: "create",
366
- description: "Create refunds",
367
- category: "Finance",
368
- sensitivity: "HIGHLY_SENSITIVE",
369
- scope: "TENANT",
370
- requiresApproval: true,
371
- },
372
- {
373
- code: "refunds.approve",
374
- resource: "refunds",
375
- action: "approve",
376
- description: "Approve refunds",
377
- category: "Finance",
378
- sensitivity: "CRITICAL",
379
- scope: "TENANT",
380
- requiresMFA: true,
381
- },
382
- {
383
- code: "subscriptions.read",
384
- resource: "subscriptions",
385
- action: "read",
386
- description: "View subscriptions",
387
- category: "Finance",
388
- sensitivity: "SENSITIVE",
389
- scope: "TENANT",
390
- },
391
- {
392
- code: "subscriptions.manage",
393
- resource: "subscriptions",
394
- action: "manage",
395
- description: "Manage subscriptions",
396
- category: "Finance",
397
- sensitivity: "SENSITIVE",
398
- scope: "TENANT",
399
- },
400
- {
401
- code: "reports.financial",
402
- resource: "reports",
403
- action: "financial",
404
- description: "Generate financial reports",
405
- category: "Finance",
406
- sensitivity: "HIGHLY_SENSITIVE",
407
- scope: "GLOBAL",
408
- },
409
- {
410
- code: "analytics.revenue",
411
- resource: "analytics",
412
- action: "revenue",
413
- description: "View revenue analytics",
414
- category: "Finance",
415
- sensitivity: "HIGHLY_SENSITIVE",
416
- scope: "GLOBAL",
417
- },
418
- // ===========================
419
- // MARKETING (10 capabilities)
420
- // ===========================
421
- {
422
- code: "campaigns.read",
423
- resource: "campaigns",
424
- action: "read",
425
- description: "View marketing campaigns",
426
- category: "Marketing",
427
- sensitivity: "NORMAL",
428
- scope: "SPACE",
429
- },
430
- {
431
- code: "campaigns.create",
432
- resource: "campaigns",
433
- action: "create",
434
- description: "Create new campaigns",
435
- category: "Marketing",
436
- sensitivity: "NORMAL",
437
- scope: "SPACE",
438
- },
439
- {
440
- code: "campaigns.update",
441
- resource: "campaigns",
442
- action: "update",
443
- description: "Update existing campaigns",
444
- category: "Marketing",
445
- sensitivity: "NORMAL",
446
- scope: "SPACE",
447
- },
448
- {
449
- code: "campaigns.delete",
450
- resource: "campaigns",
451
- action: "delete",
452
- description: "Delete campaigns",
453
- category: "Marketing",
454
- sensitivity: "SENSITIVE",
455
- scope: "SPACE",
456
- requiresApproval: true,
457
- },
458
- {
459
- code: "emails.send",
460
- resource: "emails",
461
- action: "send",
462
- description: "Send marketing emails",
463
- category: "Marketing",
464
- sensitivity: "SENSITIVE",
465
- scope: "SPACE",
466
- },
467
- {
468
- code: "emails.templates",
469
- resource: "emails",
470
- action: "templates",
471
- description: "Manage email templates",
472
- category: "Marketing",
473
- sensitivity: "NORMAL",
474
- scope: "SPACE",
475
- },
476
- {
477
- code: "analytics.marketing",
478
- resource: "analytics",
479
- action: "marketing",
480
- description: "View marketing analytics",
481
- category: "Marketing",
482
- sensitivity: "NORMAL",
483
- scope: "SPACE",
484
- },
485
- {
486
- code: "leads.read",
487
- resource: "leads",
488
- action: "read",
489
- description: "View leads",
490
- category: "Marketing",
491
- sensitivity: "SENSITIVE",
492
- scope: "SPACE",
493
- },
494
- {
495
- code: "leads.manage",
496
- resource: "leads",
497
- action: "manage",
498
- description: "Manage leads",
499
- category: "Marketing",
500
- sensitivity: "SENSITIVE",
501
- scope: "SPACE",
502
- },
503
- {
504
- code: "content.publish",
505
- resource: "content",
506
- action: "publish",
507
- description: "Publish content",
508
- category: "Marketing",
509
- sensitivity: "NORMAL",
510
- scope: "SPACE",
511
- },
512
- // ===========================
513
- // MANAGEMENT (11 capabilities)
514
- // ===========================
515
- {
516
- code: "users.read",
517
- resource: "users",
518
- action: "read",
519
- description: "View users",
520
- category: "Management",
521
- sensitivity: "SENSITIVE",
522
- scope: "TENANT",
523
- },
524
- {
525
- code: "users.create",
526
- resource: "users",
527
- action: "create",
528
- description: "Create new users",
529
- category: "Management",
530
- sensitivity: "SENSITIVE",
531
- scope: "TENANT",
532
- },
533
- {
534
- code: "users.update",
535
- resource: "users",
536
- action: "update",
537
- description: "Update existing users",
538
- category: "Management",
539
- sensitivity: "SENSITIVE",
540
- scope: "TENANT",
541
- },
542
- {
543
- code: "users.delete",
544
- resource: "users",
545
- action: "delete",
546
- description: "Delete users",
547
- category: "Management",
548
- sensitivity: "HIGHLY_SENSITIVE",
549
- scope: "TENANT",
550
- requiresApproval: true,
551
- },
552
- {
553
- code: "roles.read",
554
- resource: "roles",
555
- action: "read",
556
- description: "View roles and permissions",
557
- category: "Management",
558
- sensitivity: "SENSITIVE",
559
- scope: "SPACE",
560
- },
561
- {
562
- code: "roles.manage",
563
- resource: "roles",
564
- action: "manage",
565
- description: "Manage roles and permissions",
566
- category: "Management",
567
- sensitivity: "CRITICAL",
568
- scope: "SPACE",
569
- requiresMFA: true,
570
- requiresApproval: true,
571
- },
572
- {
573
- code: "audit.read",
574
- resource: "audit",
575
- action: "read",
576
- description: "View audit logs",
577
- category: "Management",
578
- sensitivity: "HIGHLY_SENSITIVE",
579
- scope: "GLOBAL",
580
- },
581
- {
582
- code: "audit.export",
583
- resource: "audit",
584
- action: "export",
585
- description: "Export audit logs",
586
- category: "Management",
587
- sensitivity: "CRITICAL",
588
- scope: "GLOBAL",
589
- requiresMFA: true,
590
- requiresApproval: true,
591
- },
592
- {
593
- code: "settings.read",
594
- resource: "settings",
595
- action: "read",
596
- description: "View platform settings",
597
- category: "Management",
598
- sensitivity: "SENSITIVE",
599
- scope: "GLOBAL",
600
- },
601
- {
602
- code: "settings.manage",
603
- resource: "settings",
604
- action: "manage",
605
- description: "Manage platform settings",
606
- category: "Management",
607
- sensitivity: "CRITICAL",
608
- scope: "GLOBAL",
609
- requiresMFA: true,
610
- requiresApproval: true,
611
- },
612
- {
613
- code: "impersonate.user",
614
- resource: "impersonate",
615
- action: "user",
616
- description: "Impersonate other users",
617
- category: "Management",
618
- sensitivity: "CRITICAL",
619
- scope: "GLOBAL",
620
- requiresMFA: true,
621
- requiresApproval: true,
622
- },
623
- {
624
- code: "users.export",
625
- resource: "users",
626
- action: "export",
627
- description: "Export user list (CSV)",
628
- category: "Management",
629
- sensitivity: "HIGHLY_SENSITIVE",
630
- scope: "TENANT",
631
- requiresMFA: true,
632
- requiresApproval: true,
633
- },
634
- ];
635
- // ---------------------------------------------------------------------------
636
- // Tier presets — which capability codes are enabled per tier
637
- // ---------------------------------------------------------------------------
638
- const TIER_PRESETS = {
639
- starter: [
640
- // Support basics
641
- "tickets.read",
642
- "tickets.create",
643
- "tickets.update",
644
- "tickets.assign",
645
- "tickets.close",
646
- "tickets.reopen",
647
- "customers.read",
648
- "kb.read",
649
- // Management basics
650
- "users.read",
651
- "users.create",
652
- "users.update",
653
- "roles.read",
654
- "settings.read",
655
- ],
656
- complete: [
657
- // All Starter capabilities
658
- "tickets.read",
659
- "tickets.create",
660
- "tickets.update",
661
- "tickets.assign",
662
- "tickets.close",
663
- "tickets.reopen",
664
- "tickets.delete",
665
- "tickets.export",
666
- "customers.read",
667
- "customers.update",
668
- "kb.read",
669
- "kb.manage",
670
- // DevOps basics
671
- "deployments.read",
672
- "logs.read",
673
- "monitoring.read",
674
- "monitoring.manage",
675
- "incidents.manage",
676
- // Finance basics
677
- "invoices.read",
678
- "invoices.create",
679
- "payments.read",
680
- "subscriptions.read",
681
- "subscriptions.manage",
682
- // Marketing
683
- "campaigns.read",
684
- "campaigns.create",
685
- "campaigns.update",
686
- "emails.templates",
687
- "analytics.marketing",
688
- "leads.read",
689
- "content.publish",
690
- // Management
691
- "users.read",
692
- "users.create",
693
- "users.update",
694
- "users.delete",
695
- "roles.read",
696
- "roles.manage",
697
- "settings.read",
698
- "settings.manage",
699
- ],
700
- pro: [
701
- // All Complete capabilities
702
- "tickets.read",
703
- "tickets.create",
704
- "tickets.update",
705
- "tickets.assign",
706
- "tickets.close",
707
- "tickets.reopen",
708
- "tickets.delete",
709
- "tickets.export",
710
- "customers.read",
711
- "customers.update",
712
- "kb.read",
713
- "kb.manage",
714
- "auth.2fa_reset.request",
715
- // DevOps extended
716
- "servers.read",
717
- "deployments.read",
718
- "deployments.create",
719
- "logs.read",
720
- "logs.export",
721
- "monitoring.read",
722
- "monitoring.manage",
723
- "database.read",
724
- "incidents.manage",
725
- // Finance extended
726
- "invoices.read",
727
- "invoices.create",
728
- "invoices.update",
729
- "payments.read",
730
- "payments.process",
731
- "refunds.create",
732
- "refunds.approve",
733
- "subscriptions.read",
734
- "subscriptions.manage",
735
- "reports.financial",
736
- "analytics.revenue",
737
- // Marketing full
738
- "campaigns.read",
739
- "campaigns.create",
740
- "campaigns.update",
741
- "campaigns.delete",
742
- "emails.send",
743
- "emails.templates",
744
- "analytics.marketing",
745
- "leads.read",
746
- "leads.manage",
747
- "content.publish",
748
- // Management extended
749
- "users.read",
750
- "users.create",
751
- "users.update",
752
- "users.delete",
753
- "users.export",
754
- "roles.read",
755
- "roles.manage",
756
- "audit.read",
757
- "settings.read",
758
- "settings.manage",
759
- ],
760
- enterprise: exports.ALL_CAPABILITIES.map((c) => c.code),
761
- };
762
- // ---------------------------------------------------------------------------
763
- // Helpers
764
- // ---------------------------------------------------------------------------
765
- function sensitivityBadge(s) {
766
- switch (s) {
767
- case "NORMAL":
768
- return chalk_1.default.green("[NORMAL]");
769
- case "SENSITIVE":
770
- return chalk_1.default.yellow("[SENSITIVE]");
771
- case "HIGHLY_SENSITIVE":
772
- return chalk_1.default.red("[HIGH]");
773
- case "CRITICAL":
774
- return chalk_1.default.bgRed.white("[CRITICAL]");
775
- }
776
- }
777
- function groupByCategory(caps) {
778
- const map = new Map();
779
- for (const cap of caps) {
780
- const existing = map.get(cap.category) ?? [];
781
- existing.push(cap);
782
- map.set(cap.category, existing);
783
- }
784
- return map;
785
- }
786
- function tierLabel(tier) {
787
- const labels = {
788
- starter: chalk_1.default.green("Starter"),
789
- complete: chalk_1.default.yellow("Complete"),
790
- pro: chalk_1.default.magenta("Pro"),
791
- enterprise: chalk_1.default.cyan("Enterprise"),
792
- };
793
- return labels[tier];
794
- }
795
- // ---------------------------------------------------------------------------
796
- // Seed file generator
797
- // ---------------------------------------------------------------------------
798
- function generateSeedFile(selectedCodes) {
799
- const selectedSet = new Set(selectedCodes);
800
- const selected = exports.ALL_CAPABILITIES.filter((c) => selectedSet.has(c.code));
801
- const grouped = groupByCategory(selected);
802
- const blocks = [];
803
- for (const [category, caps] of grouped) {
804
- const items = caps
805
- .map((c) => {
806
- const lines = [
807
- ` {`,
808
- ` code: '${c.code}',`,
809
- ` resource: '${c.resource}',`,
810
- ` action: '${c.action}',`,
811
- ` description: '${c.description}',`,
812
- ` category: '${c.category}',`,
813
- ` sensitivity: CapabilitySensitivity.${c.sensitivity},`,
814
- ` scope: CapabilityScope.${c.scope},`,
815
- ];
816
- if (c.requiresMFA)
817
- lines.push(` requiresMFA: true,`);
818
- if (c.requiresApproval)
819
- lines.push(` requiresApproval: true,`);
820
- lines.push(` },`);
821
- return lines.join("\n");
822
- })
823
- .join("\n");
824
- blocks.push(` // ===========================\n // ${category.toUpperCase()} (${caps.length} capabilities)\n // ===========================\n${items}`);
10
+ const capabilities_catalog_1 = require("../../lib/capabilities-catalog");
11
+ async function configFeatures(options) {
12
+ const outputPath = options.outputPath ??
13
+ path_1.default.join(process.cwd(), "packages", "database", "prisma", "seeds", "capabilities.seed.ts");
14
+ if (options.list) {
15
+ printList();
16
+ return;
825
17
  }
826
- return `import { PrismaClient, CapabilitySensitivity, CapabilityScope } from '@prisma/client';
827
-
828
- const prisma = new PrismaClient();
829
-
830
- /**
831
- * Seed de Capabilities gerado por: kaven config features
832
- * Generated at: ${new Date().toISOString()}
833
- *
834
- * Total: ${selected.length} capabilities
835
- * Categories: ${[...grouped.keys()].join(', ')}
836
- */
837
-
838
- export async function seedCapabilities() {
839
- console.log('🔐 Seeding Capabilities...');
840
-
841
- const capabilities = [
842
- ${blocks.join("\n\n")}
843
- ];
844
-
845
- let created = 0;
846
- let skipped = 0;
847
-
848
- for (const capability of capabilities) {
849
- const existing = await prisma.capability.findUnique({
850
- where: { code: capability.code },
851
- });
852
-
853
- if (existing) {
854
- skipped++;
855
- continue;
18
+ if (options.tier) {
19
+ await applyTierDirect(options.tier, outputPath, options);
20
+ return;
856
21
  }
857
-
858
- await prisma.capability.create({
859
- data: capability,
860
- });
861
- created++;
862
- }
863
-
864
- console.log(\`✅ Capabilities: \${created} criadas, \${skipped} já existiam\`);
865
- console.log(\`📊 Total de capabilities: \${capabilities.length}\`);
866
- }
867
- `;
22
+ await runInteractive(outputPath, options);
868
23
  }
869
- // ---------------------------------------------------------------------------
870
- // --list mode
871
- // ---------------------------------------------------------------------------
872
24
  function printList() {
873
- const grouped = groupByCategory(exports.ALL_CAPABILITIES);
874
25
  console.log();
875
26
  console.log(chalk_1.default.bold.underline("Kaven Framework — Capability Catalog"));
876
- console.log(chalk_1.default.gray(`${exports.ALL_CAPABILITIES.length} capabilities total\n`));
877
- for (const [category, caps] of grouped) {
27
+ console.log(chalk_1.default.gray(`${capabilities_catalog_1.ALL_CAPABILITIES.length} capabilities total\n`));
28
+ const categories = [...new Set(capabilities_catalog_1.ALL_CAPABILITIES.map(c => c.category))];
29
+ for (const category of categories) {
30
+ const caps = capabilities_catalog_1.ALL_CAPABILITIES.filter(c => c.category === category);
878
31
  console.log(chalk_1.default.bold.cyan(` ${category} (${caps.length})`));
879
32
  for (const cap of caps) {
880
- const flags = [];
881
- if (cap.requiresMFA)
882
- flags.push(chalk_1.default.red("MFA"));
883
- if (cap.requiresApproval)
884
- flags.push(chalk_1.default.yellow("APPROVAL"));
885
- const flagStr = flags.length > 0 ? ` ${flags.join(" ")}` : "";
886
- console.log(` ${chalk_1.default.white(cap.code.padEnd(30))} ${sensitivityBadge(cap.sensitivity)}${flagStr}`);
33
+ console.log(` ${chalk_1.default.white(cap.key.padEnd(30))} ${chalk_1.default.gray(`[${cap.type}]`)}`);
887
34
  console.log(` ${chalk_1.default.gray(cap.description)}`);
888
35
  }
889
36
  console.log();
890
37
  }
891
38
  console.log(chalk_1.default.bold("Tier presets:"));
892
39
  for (const tier of ["starter", "complete", "pro", "enterprise"]) {
893
- console.log(` ${tierLabel(tier).padEnd(20)} ${chalk_1.default.gray(`${TIER_PRESETS[tier].length} capabilities`)}`);
40
+ console.log(` ${chalk_1.default.white(tier.padEnd(12))}`);
894
41
  }
895
42
  console.log();
896
43
  }
897
- // ---------------------------------------------------------------------------
898
- // Non-interactive --tier mode
899
- // ---------------------------------------------------------------------------
900
- async function applyTierDirect(tier, outputPath) {
901
- const codes = TIER_PRESETS[tier];
902
- console.log();
903
- console.log(`${chalk_1.default.bold("Applying tier:")} ${tierLabel(tier)} (${codes.length} capabilities)`);
904
- const content = generateSeedFile(codes);
905
- await fs_extra_1.default.ensureDir(path_1.default.dirname(outputPath));
906
- await fs_extra_1.default.writeFile(outputPath, content, "utf-8");
907
- console.log(chalk_1.default.green(`✅ Seed file written to: ${outputPath}`));
908
- console.log(chalk_1.default.gray("Run `pnpm prisma db seed` to apply capabilities to your database."));
909
- console.log();
44
+ async function applyTierDirect(tier, outputPath, options) {
45
+ const defaults = capabilities_catalog_1.TIER_DEFAULTS[tier] || {};
46
+ const selections = {};
47
+ for (const cap of capabilities_catalog_1.ALL_CAPABILITIES) {
48
+ if (tier === "enterprise") {
49
+ selections[cap.key] = cap.type === "boolean" ? true : "-1";
50
+ }
51
+ else {
52
+ selections[cap.key] = defaults[cap.key] ?? (cap.type === "boolean" ? false : cap.defaultValue);
53
+ }
54
+ }
55
+ await saveSeedFile(selections, outputPath, options, tier);
910
56
  }
911
- // ---------------------------------------------------------------------------
912
- // Interactive TUI mode
913
- // ---------------------------------------------------------------------------
914
- async function runInteractive(outputPath) {
915
- const { select, confirm } = await import("@inquirer/prompts");
916
- // checkbox está disponível em runtime via @inquirer/prompts mas a definição de tipos
917
- // não resolve @inquirer/checkbox no node_modules direto (pacote linkado via pnpm store).
57
+ async function runInteractive(outputPath, options) {
58
+ const { select, confirm, input } = await import("@inquirer/prompts");
918
59
  // eslint-disable-next-line @typescript-eslint/no-require-imports
919
- const checkboxMod = require("@inquirer/prompts");
920
- const checkbox = checkboxMod.checkbox;
60
+ const prompts = require("@inquirer/prompts");
61
+ const checkbox = prompts.checkbox;
921
62
  console.log();
922
- console.log(chalk_1.default.bold.underline("Kaven Feature Flag Configuration"));
923
- console.log(chalk_1.default.gray("Select a base tier and optionally customize individual capabilities.\n"));
924
- // Step 1: Base tier selection
925
- const tierChoices = ["starter", "complete", "pro", "enterprise"].map((t) => ({
926
- name: `${tierLabel(t)} — ${TIER_PRESETS[t].length} capabilities`,
927
- value: t,
928
- }));
929
- tierChoices.push({ name: chalk_1.default.red("Cancel"), value: "cancel" });
63
+ console.log(chalk_1.default.bold.underline("🛡️ Kaven Feature Flag Configuration"));
930
64
  const selectedTier = await select({
931
65
  message: "Select a base tier:",
932
- choices: tierChoices,
66
+ choices: [
67
+ { name: "Starter (Essential SaaS features)", value: "starter" },
68
+ { name: "Complete (White-label + Custom Domains)", value: "complete" },
69
+ { name: "Pro (Extended API + Limits)", value: "pro" },
70
+ { name: "Enterprise (Unlimited everything)", value: "enterprise" },
71
+ { name: "Cancel", value: "cancel" },
72
+ ],
933
73
  });
934
- if (selectedTier === "cancel") {
935
- console.log(chalk_1.default.yellow("Cancelled."));
74
+ if (selectedTier === "cancel")
936
75
  return;
937
- }
938
- const baseCodes = new Set(TIER_PRESETS[selectedTier]);
939
- console.log(`\n${chalk_1.default.green("✓")} Base: ${tierLabel(selectedTier)} — ${baseCodes.size} capabilities loaded\n`);
940
- // Step 2: Optional customization per category
76
+ const tier = selectedTier;
77
+ const defaults = capabilities_catalog_1.TIER_DEFAULTS[tier] || {};
78
+ const selections = {};
941
79
  const customize = await confirm({
942
80
  message: "Customize individual capabilities?",
943
81
  default: false,
944
82
  });
945
- let finalCodes;
946
83
  if (!customize) {
947
- finalCodes = [...baseCodes];
84
+ return applyTierDirect(tier, outputPath, options);
948
85
  }
949
- else {
950
- const grouped = groupByCategory(exports.ALL_CAPABILITIES);
951
- const customSelected = [];
952
- for (const [category, caps] of grouped) {
953
- console.log(`\n${chalk_1.default.bold.cyan(` ${category}`)}`);
954
- const choices = caps.map((c) => {
955
- const flags = [];
956
- if (c.requiresMFA)
957
- flags.push("MFA");
958
- if (c.requiresApproval)
959
- flags.push("APPROVAL");
960
- const flagStr = flags.length > 0 ? ` [${flags.join(",")}]` : "";
961
- return {
962
- name: `${c.code.padEnd(32)} ${sensitivityBadge(c.sensitivity)}${flagStr} — ${c.description}`,
963
- value: c.code,
964
- checked: baseCodes.has(c.code),
965
- };
966
- });
86
+ const categories = [...new Set(capabilities_catalog_1.ALL_CAPABILITIES.map(c => c.category))];
87
+ for (const category of categories) {
88
+ const caps = capabilities_catalog_1.ALL_CAPABILITIES.filter(c => c.category === category);
89
+ const boolCaps = caps.filter(c => c.type === "boolean");
90
+ const numCaps = caps.filter(c => c.type === "numeric");
91
+ if (boolCaps.length > 0) {
92
+ const choices = boolCaps.map(c => ({
93
+ name: `${c.key.padEnd(30)} — ${c.description}`,
94
+ value: c.key,
95
+ checked: tier === "enterprise" ? true : (defaults[c.key] === true),
96
+ }));
967
97
  const selected = await checkbox({
968
- message: `${category} capabilities:`,
98
+ message: `${category} features:`,
969
99
  choices,
970
100
  });
971
- customSelected.push(...selected);
101
+ for (const cap of boolCaps) {
102
+ selections[cap.key] = selected.includes(cap.key);
103
+ }
104
+ }
105
+ for (const cap of numCaps) {
106
+ const defVal = tier === "enterprise" ? "-1" : (defaults[cap.key] || cap.defaultValue);
107
+ const val = await input({
108
+ message: `${cap.key} (${cap.description}):`,
109
+ default: defVal,
110
+ });
111
+ selections[cap.key] = val;
972
112
  }
973
- finalCodes = customSelected;
974
- }
975
- if (finalCodes.length === 0) {
976
- console.log(chalk_1.default.yellow("\nNo capabilities selected. Seed file not written."));
977
- return;
978
- }
979
- // Step 3: Preview and confirm
980
- const grouped = groupByCategory(exports.ALL_CAPABILITIES.filter((c) => finalCodes.includes(c.code)));
981
- console.log();
982
- console.log(chalk_1.default.bold.underline("Summary:"));
983
- for (const [category, caps] of grouped) {
984
- console.log(` ${chalk_1.default.cyan(category)}: ${caps.length} capabilities`);
985
113
  }
986
- console.log(` ${chalk_1.default.bold("Total:")} ${finalCodes.length} capabilities`);
987
- console.log(` ${chalk_1.default.bold("Output:")} ${chalk_1.default.dim(outputPath)}`);
988
- console.log();
989
- const proceed = await confirm({
990
- message: "Write capabilities.seed.ts?",
991
- default: true,
114
+ await saveSeedFile(selections, outputPath, options, tier);
115
+ }
116
+ async function saveSeedFile(selections, outputPath, options, tier) {
117
+ const items = capabilities_catalog_1.ALL_CAPABILITIES.map(c => {
118
+ const val = selections[c.key];
119
+ return ` { key: "${c.key}", type: "${c.type}", defaultValue: "${val}", description: "${c.description}" },`;
120
+ }).join("\n");
121
+ const content = `// packages/database/prisma/seeds/capabilities.seed.ts
122
+ // Generated by kaven config features — ${new Date().toISOString()}
123
+ // Tier: ${tier}
124
+
125
+ import { PrismaClient } from "@prisma/client";
126
+
127
+ export async function seedCapabilities(prisma: PrismaClient) {
128
+ const capabilities = [
129
+ ${items}
130
+ ];
131
+
132
+ console.log("🔐 Seeding ${capabilities_catalog_1.ALL_CAPABILITIES.length} Capabilities...");
133
+
134
+ for (const cap of capabilities) {
135
+ await prisma.capability.upsert({
136
+ where: { key: cap.key },
137
+ update: cap,
138
+ create: cap,
992
139
  });
993
- if (!proceed) {
994
- console.log(chalk_1.default.yellow("Cancelled."));
140
+ }
141
+ }
142
+ `;
143
+ if (options.dryRun) {
144
+ console.log(chalk_1.default.bold("\n--- DRY RUN: Generated Content ---"));
145
+ console.log(content);
995
146
  return;
996
147
  }
997
- const content = generateSeedFile(finalCodes);
148
+ if (fs_extra_1.default.existsSync(outputPath) && !options.force) {
149
+ const { confirm: confirmOverwrite } = await import("@inquirer/prompts");
150
+ const overwrite = await confirmOverwrite({
151
+ message: "Seed file already exists. Overwrite?",
152
+ default: false,
153
+ });
154
+ if (!overwrite)
155
+ return;
156
+ }
998
157
  await fs_extra_1.default.ensureDir(path_1.default.dirname(outputPath));
999
158
  await fs_extra_1.default.writeFile(outputPath, content, "utf-8");
1000
159
  console.log(chalk_1.default.green(`\n✅ Seed file written to: ${outputPath}`));
1001
- console.log(chalk_1.default.gray("Run `pnpm prisma db seed` to apply capabilities to your database.\n"));
1002
- }
1003
- // ---------------------------------------------------------------------------
1004
- // Public entry point
1005
- // ---------------------------------------------------------------------------
1006
- async function configFeatures(options) {
1007
- const outputPath = options.outputPath ??
1008
- path_1.default.join(process.cwd(), "packages", "database", "prisma", "seeds", "capabilities.seed.ts");
1009
- // --list: just print the catalog, no writes
1010
- if (options.list) {
1011
- printList();
1012
- return;
1013
- }
1014
- // --tier: non-interactive direct apply
1015
- if (options.tier) {
1016
- const validTiers = ["starter", "complete", "pro", "enterprise"];
1017
- if (!validTiers.includes(options.tier)) {
1018
- console.error(chalk_1.default.red(`Error: Invalid tier "${options.tier}". Valid options: ${validTiers.join(", ")}`));
1019
- process.exit(1);
1020
- }
1021
- await applyTierDirect(options.tier, outputPath);
1022
- return;
1023
- }
1024
- // Interactive TUI
1025
- await runInteractive(outputPath);
160
+ console.log(chalk_1.default.gray("Run pnpm prisma db seed to apply capabilities to your database."));
1026
161
  }