chainlesschain 0.66.0 → 0.132.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.
Files changed (143) hide show
  1. package/bin/chainlesschain.js +0 -0
  2. package/package.json +1 -1
  3. package/src/commands/a2a.js +380 -0
  4. package/src/commands/agent-network.js +254 -1
  5. package/src/commands/audit.js +302 -0
  6. package/src/commands/automation.js +271 -1
  7. package/src/commands/bi.js +348 -0
  8. package/src/commands/codegen.js +224 -0
  9. package/src/commands/collab.js +341 -0
  10. package/src/commands/compliance.js +1035 -0
  11. package/src/commands/cowork.js +221 -0
  12. package/src/commands/crosschain.js +218 -0
  13. package/src/commands/dbevo.js +284 -0
  14. package/src/commands/dev.js +252 -0
  15. package/src/commands/did.js +358 -0
  16. package/src/commands/dlp.js +341 -0
  17. package/src/commands/encrypt.js +341 -0
  18. package/src/commands/evomap.js +394 -0
  19. package/src/commands/export.js +256 -1
  20. package/src/commands/federation.js +283 -0
  21. package/src/commands/fusion.js +258 -0
  22. package/src/commands/governance.js +325 -0
  23. package/src/commands/hardening.js +411 -0
  24. package/src/commands/hook.js +148 -0
  25. package/src/commands/import.js +252 -0
  26. package/src/commands/incentive.js +322 -0
  27. package/src/commands/inference.js +318 -0
  28. package/src/commands/infra.js +244 -0
  29. package/src/commands/instinct.js +260 -0
  30. package/src/commands/ipfs.js +318 -0
  31. package/src/commands/kg.js +387 -0
  32. package/src/commands/llm.js +263 -0
  33. package/src/commands/lowcode.js +356 -0
  34. package/src/commands/marketplace.js +256 -0
  35. package/src/commands/mcp.js +221 -0
  36. package/src/commands/memory.js +248 -0
  37. package/src/commands/multimodal.js +296 -0
  38. package/src/commands/nlprog.js +356 -0
  39. package/src/commands/note.js +244 -0
  40. package/src/commands/ops.js +354 -0
  41. package/src/commands/orchestrate.js +166 -0
  42. package/src/commands/org.js +277 -0
  43. package/src/commands/p2p.js +390 -0
  44. package/src/commands/perception.js +290 -0
  45. package/src/commands/permmem.js +251 -0
  46. package/src/commands/plugin-ecosystem.js +273 -0
  47. package/src/commands/pqc.js +393 -0
  48. package/src/commands/privacy.js +321 -0
  49. package/src/commands/quantization.js +351 -0
  50. package/src/commands/rcache.js +271 -0
  51. package/src/commands/recommend.js +340 -0
  52. package/src/commands/reputation.js +261 -0
  53. package/src/commands/runtime.js +307 -0
  54. package/src/commands/scim.js +262 -0
  55. package/src/commands/session.js +258 -0
  56. package/src/commands/siem.js +246 -0
  57. package/src/commands/skill.js +267 -1
  58. package/src/commands/sla.js +259 -0
  59. package/src/commands/social.js +256 -0
  60. package/src/commands/sso.js +186 -1
  61. package/src/commands/stress.js +230 -0
  62. package/src/commands/sync.js +256 -0
  63. package/src/commands/tech.js +338 -0
  64. package/src/commands/tenant.js +351 -0
  65. package/src/commands/terraform.js +245 -0
  66. package/src/commands/tokens.js +269 -0
  67. package/src/commands/trust.js +249 -0
  68. package/src/commands/wallet.js +277 -0
  69. package/src/commands/workflow.js +171 -0
  70. package/src/commands/zkp.js +335 -0
  71. package/src/index.js +4 -0
  72. package/src/lib/a2a-protocol.js +451 -0
  73. package/src/lib/agent-coordinator.js +325 -0
  74. package/src/lib/agent-network.js +387 -0
  75. package/src/lib/agent-router.js +395 -0
  76. package/src/lib/aiops.js +478 -0
  77. package/src/lib/app-builder.js +239 -0
  78. package/src/lib/audit-logger.js +379 -0
  79. package/src/lib/automation-engine.js +330 -0
  80. package/src/lib/autonomous-developer.js +350 -0
  81. package/src/lib/bi-engine.js +338 -0
  82. package/src/lib/code-agent.js +323 -0
  83. package/src/lib/collaboration-governance.js +364 -0
  84. package/src/lib/community-governance.js +436 -0
  85. package/src/lib/compliance-manager.js +434 -0
  86. package/src/lib/content-recommendation.js +469 -0
  87. package/src/lib/cross-chain.js +345 -0
  88. package/src/lib/crypto-manager.js +350 -0
  89. package/src/lib/dbevo.js +338 -0
  90. package/src/lib/decentral-infra.js +340 -0
  91. package/src/lib/did-manager.js +367 -0
  92. package/src/lib/dlp-engine.js +389 -0
  93. package/src/lib/evomap-federation.js +177 -0
  94. package/src/lib/evomap-governance.js +276 -0
  95. package/src/lib/federation-hardening.js +259 -0
  96. package/src/lib/hardening-manager.js +348 -0
  97. package/src/lib/hook-manager.js +380 -0
  98. package/src/lib/inference-network.js +330 -0
  99. package/src/lib/instinct-manager.js +332 -0
  100. package/src/lib/ipfs-storage.js +334 -0
  101. package/src/lib/knowledge-exporter.js +381 -0
  102. package/src/lib/knowledge-graph.js +432 -0
  103. package/src/lib/knowledge-importer.js +379 -0
  104. package/src/lib/llm-providers.js +391 -0
  105. package/src/lib/mcp-registry.js +333 -0
  106. package/src/lib/memory-manager.js +330 -0
  107. package/src/lib/multimodal.js +346 -0
  108. package/src/lib/nl-programming.js +343 -0
  109. package/src/lib/note-versioning.js +327 -0
  110. package/src/lib/org-manager.js +323 -0
  111. package/src/lib/p2p-manager.js +387 -0
  112. package/src/lib/perception.js +346 -0
  113. package/src/lib/perf-tuning.js +4 -1
  114. package/src/lib/permanent-memory.js +320 -0
  115. package/src/lib/plugin-ecosystem.js +377 -0
  116. package/src/lib/pqc-manager.js +368 -0
  117. package/src/lib/privacy-computing.js +427 -0
  118. package/src/lib/protocol-fusion.js +417 -0
  119. package/src/lib/quantization.js +325 -0
  120. package/src/lib/reputation-optimizer.js +299 -0
  121. package/src/lib/response-cache.js +327 -0
  122. package/src/lib/scim-manager.js +329 -0
  123. package/src/lib/session-manager.js +329 -0
  124. package/src/lib/siem-exporter.js +333 -0
  125. package/src/lib/skill-loader.js +377 -0
  126. package/src/lib/skill-marketplace.js +325 -0
  127. package/src/lib/sla-manager.js +275 -0
  128. package/src/lib/social-manager.js +326 -0
  129. package/src/lib/sso-manager.js +332 -0
  130. package/src/lib/stress-tester.js +330 -0
  131. package/src/lib/sync-manager.js +326 -0
  132. package/src/lib/tech-learning-engine.js +369 -0
  133. package/src/lib/tenant-saas.js +460 -0
  134. package/src/lib/terraform-manager.js +363 -0
  135. package/src/lib/threat-intel.js +335 -0
  136. package/src/lib/token-incentive.js +293 -0
  137. package/src/lib/token-tracker.js +329 -0
  138. package/src/lib/trust-security.js +390 -0
  139. package/src/lib/ueba.js +389 -0
  140. package/src/lib/universal-runtime.js +325 -0
  141. package/src/lib/wallet-manager.js +326 -0
  142. package/src/lib/workflow-engine.js +322 -0
  143. package/src/lib/zkp-engine.js +274 -0
@@ -21,6 +21,40 @@ import {
21
21
  getStats,
22
22
  exportGraph,
23
23
  importGraph,
24
+ // V2 surface
25
+ ENTITY_STATUS_V2,
26
+ RELATION_STATUS_V2,
27
+ KG_DEFAULT_MAX_ACTIVE_ENTITIES_PER_OWNER,
28
+ KG_DEFAULT_MAX_RELATIONS_PER_ENTITY,
29
+ KG_DEFAULT_ENTITY_STALE_MS,
30
+ KG_DEFAULT_RELATION_STALE_MS,
31
+ getMaxActiveEntitiesPerOwnerV2,
32
+ setMaxActiveEntitiesPerOwnerV2,
33
+ getMaxRelationsPerEntityV2,
34
+ setMaxRelationsPerEntityV2,
35
+ getEntityStaleMsV2,
36
+ setEntityStaleMsV2,
37
+ getRelationStaleMsV2,
38
+ setRelationStaleMsV2,
39
+ registerEntityV2,
40
+ getEntityV2,
41
+ setEntityStatusV2,
42
+ deprecateEntity,
43
+ archiveEntityV2,
44
+ removeEntityV2,
45
+ reviveEntity,
46
+ touchEntityActivity,
47
+ registerRelationV2,
48
+ getRelationV2,
49
+ setRelationStatusV2,
50
+ deprecateRelation,
51
+ removeRelationV2,
52
+ reviveRelation,
53
+ getActiveEntityCount,
54
+ getActiveRelationCount,
55
+ autoArchiveStaleEntities,
56
+ autoRemoveStaleRelations,
57
+ getKnowledgeGraphStatsV2,
24
58
  } from "../lib/knowledge-graph.js";
25
59
 
26
60
  function _dbFromCtx(ctx) {
@@ -368,4 +402,357 @@ export function registerKgCommand(program) {
368
402
  process.exit(1);
369
403
  }
370
404
  });
405
+
406
+ /* ── V2 subcommands (Phase 94) ───────────────────────────────── */
407
+
408
+ kg.command("entity-statuses-v2")
409
+ .description("List V2 entity maturity statuses")
410
+ .option("--json", "Output as JSON")
411
+ .action((options) => {
412
+ const statuses = Object.values(ENTITY_STATUS_V2);
413
+ if (options.json) {
414
+ console.log(JSON.stringify(statuses, null, 2));
415
+ } else {
416
+ for (const s of statuses) logger.log(` ${chalk.yellow(s)}`);
417
+ }
418
+ });
419
+
420
+ kg.command("relation-statuses-v2")
421
+ .description("List V2 relation statuses")
422
+ .option("--json", "Output as JSON")
423
+ .action((options) => {
424
+ const statuses = Object.values(RELATION_STATUS_V2);
425
+ if (options.json) {
426
+ console.log(JSON.stringify(statuses, null, 2));
427
+ } else {
428
+ for (const s of statuses) logger.log(` ${chalk.yellow(s)}`);
429
+ }
430
+ });
431
+
432
+ kg.command("default-max-active-entities-per-owner")
433
+ .description("Show default V2 per-owner active-entity cap")
434
+ .action(() => logger.log(String(KG_DEFAULT_MAX_ACTIVE_ENTITIES_PER_OWNER)));
435
+ kg.command("max-active-entities-per-owner")
436
+ .description("Show current V2 per-owner active-entity cap")
437
+ .action(() => logger.log(String(getMaxActiveEntitiesPerOwnerV2())));
438
+ kg.command("set-max-active-entities-per-owner <n>")
439
+ .description("Set V2 per-owner active-entity cap")
440
+ .action((n) =>
441
+ logger.log(String(setMaxActiveEntitiesPerOwnerV2(parseInt(n, 10)))),
442
+ );
443
+
444
+ kg.command("default-max-relations-per-entity")
445
+ .description("Show default V2 per-entity active-relation cap")
446
+ .action(() => logger.log(String(KG_DEFAULT_MAX_RELATIONS_PER_ENTITY)));
447
+ kg.command("max-relations-per-entity")
448
+ .description("Show current V2 per-entity active-relation cap")
449
+ .action(() => logger.log(String(getMaxRelationsPerEntityV2())));
450
+ kg.command("set-max-relations-per-entity <n>")
451
+ .description("Set V2 per-entity active-relation cap")
452
+ .action((n) =>
453
+ logger.log(String(setMaxRelationsPerEntityV2(parseInt(n, 10)))),
454
+ );
455
+
456
+ kg.command("default-entity-stale-ms")
457
+ .description("Show default V2 entity staleness threshold (ms)")
458
+ .action(() => logger.log(String(KG_DEFAULT_ENTITY_STALE_MS)));
459
+ kg.command("entity-stale-ms")
460
+ .description("Show current V2 entity staleness threshold (ms)")
461
+ .action(() => logger.log(String(getEntityStaleMsV2())));
462
+ kg.command("set-entity-stale-ms <ms>")
463
+ .description("Set V2 entity staleness threshold (ms)")
464
+ .action((ms) => logger.log(String(setEntityStaleMsV2(parseInt(ms, 10)))));
465
+
466
+ kg.command("default-relation-stale-ms")
467
+ .description("Show default V2 relation staleness threshold (ms)")
468
+ .action(() => logger.log(String(KG_DEFAULT_RELATION_STALE_MS)));
469
+ kg.command("relation-stale-ms")
470
+ .description("Show current V2 relation staleness threshold (ms)")
471
+ .action(() => logger.log(String(getRelationStaleMsV2())));
472
+ kg.command("set-relation-stale-ms <ms>")
473
+ .description("Set V2 relation staleness threshold (ms)")
474
+ .action((ms) => logger.log(String(setRelationStaleMsV2(parseInt(ms, 10)))));
475
+
476
+ kg.command("active-entity-count")
477
+ .description("Active V2 entity count (scoped by owner)")
478
+ .option("-o, --owner <id>", "Scope by owner ID")
479
+ .action((opts) => logger.log(String(getActiveEntityCount(opts.owner))));
480
+
481
+ kg.command("active-relation-count")
482
+ .description("Active V2 relation count (scoped by source entity)")
483
+ .option("-s, --source <id>", "Scope by source entity ID")
484
+ .action((opts) => logger.log(String(getActiveRelationCount(opts.source))));
485
+
486
+ kg.command("register-entity-v2 <entity-id>")
487
+ .description("Register a V2 entity")
488
+ .requiredOption("-o, --owner <id>", "Owner ID")
489
+ .option("-n, --name <name>", "Entity name")
490
+ .option("-t, --type <type>", "Entity type")
491
+ .option("-m, --metadata <json>", "JSON metadata")
492
+ .option("--json", "Output as JSON")
493
+ .action((entityId, opts) => {
494
+ try {
495
+ const metadata = opts.metadata ? JSON.parse(opts.metadata) : undefined;
496
+ const rec = registerEntityV2(null, {
497
+ entityId,
498
+ ownerId: opts.owner,
499
+ name: opts.name,
500
+ type: opts.type,
501
+ metadata,
502
+ });
503
+ if (opts.json) console.log(JSON.stringify(rec, null, 2));
504
+ else logger.success(`Entity registered: ${entityId} (${rec.status})`);
505
+ } catch (err) {
506
+ logger.error(`Failed: ${err.message}`);
507
+ process.exit(1);
508
+ }
509
+ });
510
+
511
+ kg.command("entity-v2 <entity-id>")
512
+ .description("Show V2 entity lifecycle state")
513
+ .option("--json", "Output as JSON")
514
+ .action((entityId, opts) => {
515
+ const rec = getEntityV2(entityId);
516
+ if (!rec) {
517
+ logger.error(`Entity not registered in V2: ${entityId}`);
518
+ process.exit(1);
519
+ }
520
+ if (opts.json) console.log(JSON.stringify(rec, null, 2));
521
+ else {
522
+ logger.log(` ${chalk.bold("Entity:")} ${rec.entityId}`);
523
+ logger.log(` ${chalk.bold("Status:")} ${chalk.yellow(rec.status)}`);
524
+ logger.log(` ${chalk.bold("Owner:")} ${rec.ownerId}`);
525
+ }
526
+ });
527
+
528
+ kg.command("set-entity-status-v2 <entity-id> <status>")
529
+ .description("Transition a V2 entity status")
530
+ .option("-r, --reason <text>", "Reason")
531
+ .option("-m, --metadata <json>", "JSON metadata to merge")
532
+ .action((entityId, status, opts) => {
533
+ try {
534
+ const patch = {};
535
+ if (opts.reason) patch.reason = opts.reason;
536
+ if (opts.metadata) patch.metadata = JSON.parse(opts.metadata);
537
+ const rec = setEntityStatusV2(null, entityId, status, patch);
538
+ logger.success(`Entity ${entityId} → ${rec.status}`);
539
+ } catch (err) {
540
+ logger.error(`Failed: ${err.message}`);
541
+ process.exit(1);
542
+ }
543
+ });
544
+
545
+ kg.command("deprecate-entity <entity-id>")
546
+ .description("Deprecate a V2 entity (grace period)")
547
+ .option("-r, --reason <text>", "Reason")
548
+ .action((entityId, opts) => {
549
+ try {
550
+ deprecateEntity(null, entityId, opts.reason);
551
+ logger.success(`Entity ${entityId} deprecated`);
552
+ } catch (err) {
553
+ logger.error(`Failed: ${err.message}`);
554
+ process.exit(1);
555
+ }
556
+ });
557
+
558
+ kg.command("archive-entity-v2 <entity-id>")
559
+ .description("Archive a V2 entity")
560
+ .option("-r, --reason <text>", "Reason")
561
+ .action((entityId, opts) => {
562
+ try {
563
+ archiveEntityV2(null, entityId, opts.reason);
564
+ logger.success(`Entity ${entityId} archived`);
565
+ } catch (err) {
566
+ logger.error(`Failed: ${err.message}`);
567
+ process.exit(1);
568
+ }
569
+ });
570
+
571
+ kg.command("remove-entity-v2 <entity-id>")
572
+ .description("Remove a V2 entity (terminal)")
573
+ .option("-r, --reason <text>", "Reason")
574
+ .action((entityId, opts) => {
575
+ try {
576
+ removeEntityV2(null, entityId, opts.reason);
577
+ logger.success(`Entity ${entityId} removed`);
578
+ } catch (err) {
579
+ logger.error(`Failed: ${err.message}`);
580
+ process.exit(1);
581
+ }
582
+ });
583
+
584
+ kg.command("revive-entity <entity-id>")
585
+ .description("Restore a V2 entity to active")
586
+ .option("-r, --reason <text>", "Reason")
587
+ .action((entityId, opts) => {
588
+ try {
589
+ reviveEntity(null, entityId, opts.reason);
590
+ logger.success(`Entity ${entityId} revived`);
591
+ } catch (err) {
592
+ logger.error(`Failed: ${err.message}`);
593
+ process.exit(1);
594
+ }
595
+ });
596
+
597
+ kg.command("touch-entity-activity <entity-id>")
598
+ .description("Bump lastActivityAt on a V2 entity")
599
+ .action((entityId) => {
600
+ try {
601
+ touchEntityActivity(entityId);
602
+ logger.success(`Entity ${entityId} activity bumped`);
603
+ } catch (err) {
604
+ logger.error(`Failed: ${err.message}`);
605
+ process.exit(1);
606
+ }
607
+ });
608
+
609
+ kg.command("register-relation-v2 <relation-id>")
610
+ .description("Register a V2 relation")
611
+ .requiredOption("-s, --source <id>", "Source entity ID")
612
+ .requiredOption("-t, --target <id>", "Target entity ID")
613
+ .requiredOption("-r, --relation-type <type>", "Relation type")
614
+ .option("-m, --metadata <json>", "JSON metadata")
615
+ .option("--json", "Output as JSON")
616
+ .action((relationId, opts) => {
617
+ try {
618
+ const metadata = opts.metadata ? JSON.parse(opts.metadata) : undefined;
619
+ const rec = registerRelationV2(null, {
620
+ relationId,
621
+ sourceEntityId: opts.source,
622
+ targetEntityId: opts.target,
623
+ relationType: opts.relationType,
624
+ metadata,
625
+ });
626
+ if (opts.json) console.log(JSON.stringify(rec, null, 2));
627
+ else
628
+ logger.success(`Relation registered: ${relationId} (${rec.status})`);
629
+ } catch (err) {
630
+ logger.error(`Failed: ${err.message}`);
631
+ process.exit(1);
632
+ }
633
+ });
634
+
635
+ kg.command("relation-v2 <relation-id>")
636
+ .description("Show V2 relation lifecycle state")
637
+ .option("--json", "Output as JSON")
638
+ .action((relationId, opts) => {
639
+ const rec = getRelationV2(relationId);
640
+ if (!rec) {
641
+ logger.error(`Relation not registered in V2: ${relationId}`);
642
+ process.exit(1);
643
+ }
644
+ if (opts.json) console.log(JSON.stringify(rec, null, 2));
645
+ else {
646
+ logger.log(` ${chalk.bold("Relation:")} ${rec.relationId}`);
647
+ logger.log(` ${chalk.bold("Status:")} ${chalk.yellow(rec.status)}`);
648
+ logger.log(
649
+ ` ${chalk.bold("Edge:")} ${rec.sourceEntityId} ─[${rec.relationType}]→ ${rec.targetEntityId}`,
650
+ );
651
+ }
652
+ });
653
+
654
+ kg.command("set-relation-status-v2 <relation-id> <status>")
655
+ .description("Transition a V2 relation status")
656
+ .option("-r, --reason <text>", "Reason")
657
+ .option("-m, --metadata <json>", "JSON metadata to merge")
658
+ .action((relationId, status, opts) => {
659
+ try {
660
+ const patch = {};
661
+ if (opts.reason) patch.reason = opts.reason;
662
+ if (opts.metadata) patch.metadata = JSON.parse(opts.metadata);
663
+ const rec = setRelationStatusV2(null, relationId, status, patch);
664
+ logger.success(`Relation ${relationId} → ${rec.status}`);
665
+ } catch (err) {
666
+ logger.error(`Failed: ${err.message}`);
667
+ process.exit(1);
668
+ }
669
+ });
670
+
671
+ kg.command("deprecate-relation <relation-id>")
672
+ .description("Deprecate a V2 relation")
673
+ .option("-r, --reason <text>", "Reason")
674
+ .action((relationId, opts) => {
675
+ try {
676
+ deprecateRelation(null, relationId, opts.reason);
677
+ logger.success(`Relation ${relationId} deprecated`);
678
+ } catch (err) {
679
+ logger.error(`Failed: ${err.message}`);
680
+ process.exit(1);
681
+ }
682
+ });
683
+
684
+ kg.command("remove-relation-v2 <relation-id>")
685
+ .description("Remove a V2 relation (terminal)")
686
+ .option("-r, --reason <text>", "Reason")
687
+ .action((relationId, opts) => {
688
+ try {
689
+ removeRelationV2(null, relationId, opts.reason);
690
+ logger.success(`Relation ${relationId} removed`);
691
+ } catch (err) {
692
+ logger.error(`Failed: ${err.message}`);
693
+ process.exit(1);
694
+ }
695
+ });
696
+
697
+ kg.command("revive-relation <relation-id>")
698
+ .description("Restore a V2 relation to active")
699
+ .option("-r, --reason <text>", "Reason")
700
+ .action((relationId, opts) => {
701
+ try {
702
+ reviveRelation(null, relationId, opts.reason);
703
+ logger.success(`Relation ${relationId} revived`);
704
+ } catch (err) {
705
+ logger.error(`Failed: ${err.message}`);
706
+ process.exit(1);
707
+ }
708
+ });
709
+
710
+ kg.command("auto-archive-stale-entities")
711
+ .description("Bulk-flip stale V2 entities → archived")
712
+ .option("--json", "Output as JSON")
713
+ .action((opts) => {
714
+ const flipped = autoArchiveStaleEntities(null);
715
+ if (opts.json) console.log(JSON.stringify(flipped, null, 2));
716
+ else logger.success(`Archived ${flipped.length} stale entities`);
717
+ });
718
+
719
+ kg.command("auto-remove-stale-relations")
720
+ .description("Bulk-flip stale V2 relations → removed")
721
+ .option("--json", "Output as JSON")
722
+ .action((opts) => {
723
+ const flipped = autoRemoveStaleRelations(null);
724
+ if (opts.json) console.log(JSON.stringify(flipped, null, 2));
725
+ else logger.success(`Removed ${flipped.length} stale relations`);
726
+ });
727
+
728
+ kg.command("stats-v2")
729
+ .description("V2 knowledge graph stats (all-enum-key zero-init)")
730
+ .option("--json", "Output as JSON")
731
+ .action((opts) => {
732
+ const stats = getKnowledgeGraphStatsV2();
733
+ if (opts.json) {
734
+ console.log(JSON.stringify(stats, null, 2));
735
+ } else {
736
+ logger.log(
737
+ ` ${chalk.bold("Total entities:")} ${stats.totalEntitiesV2}`,
738
+ );
739
+ logger.log(
740
+ ` ${chalk.bold("Total relations:")} ${stats.totalRelationsV2}`,
741
+ );
742
+ logger.log(
743
+ ` ${chalk.bold("Caps:")} per-owner=${stats.maxActiveEntitiesPerOwner}, per-entity=${stats.maxRelationsPerEntity}`,
744
+ );
745
+ logger.log(
746
+ ` ${chalk.bold("Stale thresholds:")} entity=${stats.entityStaleMs}ms, relation=${stats.relationStaleMs}ms`,
747
+ );
748
+ logger.log(chalk.bold(" Entities by status:"));
749
+ for (const [k, v] of Object.entries(stats.entitiesByStatus)) {
750
+ logger.log(` ${chalk.yellow(k.padEnd(12))} ${v}`);
751
+ }
752
+ logger.log(chalk.bold(" Relations by status:"));
753
+ for (const [k, v] of Object.entries(stats.relationsByStatus)) {
754
+ logger.log(` ${chalk.yellow(k.padEnd(12))} ${v}`);
755
+ }
756
+ }
757
+ });
371
758
  }
@@ -10,6 +10,37 @@ import { bootstrap, shutdown } from "../runtime/bootstrap.js";
10
10
  import {
11
11
  BUILT_IN_PROVIDERS,
12
12
  LLMProviderRegistry,
13
+ PROVIDER_MATURITY_V2,
14
+ REQUEST_LIFECYCLE_V2,
15
+ getMaxActiveProfilesPerOwnerV2,
16
+ setMaxActiveProfilesPerOwnerV2,
17
+ getMaxPendingRequestsPerProfileV2,
18
+ setMaxPendingRequestsPerProfileV2,
19
+ getProfileIdleMsV2,
20
+ setProfileIdleMsV2,
21
+ getRequestStuckMsV2,
22
+ setRequestStuckMsV2,
23
+ registerProfileV2,
24
+ getProfileV2,
25
+ listProfilesV2,
26
+ setProfileStatusV2,
27
+ activateProfileV2,
28
+ suspendProfileV2,
29
+ retireProfileV2,
30
+ touchProfileV2,
31
+ createRequestV2,
32
+ getRequestV2,
33
+ listRequestsV2,
34
+ setRequestStatusV2,
35
+ startRequestV2,
36
+ completeRequestV2,
37
+ failRequestV2,
38
+ cancelRequestV2,
39
+ getActiveProfileCountV2,
40
+ getPendingRequestCountV2,
41
+ autoSuspendIdleProfilesV2,
42
+ autoFailStuckRequestsV2,
43
+ getLlmProvidersStatsV2,
13
44
  } from "../lib/llm-providers.js";
14
45
 
15
46
  export function registerLlmCommand(program) {
@@ -285,4 +316,236 @@ export function registerLlmCommand(program) {
285
316
  process.exit(1);
286
317
  }
287
318
  });
319
+
320
+ // ─── V2 Governance Layer ──────────────────────────────────────────
321
+ const out = (obj) => console.log(JSON.stringify(obj, null, 2));
322
+ const tryRun = (fn) => {
323
+ try {
324
+ fn();
325
+ } catch (err) {
326
+ logger.error(err.message);
327
+ process.exit(1);
328
+ }
329
+ };
330
+
331
+ llm
332
+ .command("provider-maturities-v2")
333
+ .description("List V2 provider maturity states")
334
+ .action(() => out(Object.values(PROVIDER_MATURITY_V2)));
335
+
336
+ llm
337
+ .command("request-lifecycles-v2")
338
+ .description("List V2 request lifecycle states")
339
+ .action(() => out(Object.values(REQUEST_LIFECYCLE_V2)));
340
+
341
+ llm
342
+ .command("stats-v2")
343
+ .description("V2 llm-providers stats")
344
+ .action(() => out(getLlmProvidersStatsV2()));
345
+
346
+ llm
347
+ .command("get-max-active-profiles-v2")
348
+ .description("Get max active profiles per owner (V2)")
349
+ .action(() =>
350
+ out({ maxActiveProfilesPerOwner: getMaxActiveProfilesPerOwnerV2() }),
351
+ );
352
+
353
+ llm
354
+ .command("set-max-active-profiles-v2 <n>")
355
+ .description("Set max active profiles per owner (V2)")
356
+ .action((n) =>
357
+ tryRun(() => {
358
+ setMaxActiveProfilesPerOwnerV2(Number(n));
359
+ out({ maxActiveProfilesPerOwner: getMaxActiveProfilesPerOwnerV2() });
360
+ }),
361
+ );
362
+
363
+ llm
364
+ .command("get-max-pending-requests-v2")
365
+ .description("Get max pending requests per profile (V2)")
366
+ .action(() =>
367
+ out({
368
+ maxPendingRequestsPerProfile: getMaxPendingRequestsPerProfileV2(),
369
+ }),
370
+ );
371
+
372
+ llm
373
+ .command("set-max-pending-requests-v2 <n>")
374
+ .description("Set max pending requests per profile (V2)")
375
+ .action((n) =>
376
+ tryRun(() => {
377
+ setMaxPendingRequestsPerProfileV2(Number(n));
378
+ out({
379
+ maxPendingRequestsPerProfile: getMaxPendingRequestsPerProfileV2(),
380
+ });
381
+ }),
382
+ );
383
+
384
+ llm
385
+ .command("get-profile-idle-ms-v2")
386
+ .description("Get profile idle threshold (V2)")
387
+ .action(() => out({ profileIdleMs: getProfileIdleMsV2() }));
388
+
389
+ llm
390
+ .command("set-profile-idle-ms-v2 <ms>")
391
+ .description("Set profile idle threshold (V2)")
392
+ .action((ms) =>
393
+ tryRun(() => {
394
+ setProfileIdleMsV2(Number(ms));
395
+ out({ profileIdleMs: getProfileIdleMsV2() });
396
+ }),
397
+ );
398
+
399
+ llm
400
+ .command("get-request-stuck-ms-v2")
401
+ .description("Get request stuck threshold (V2)")
402
+ .action(() => out({ requestStuckMs: getRequestStuckMsV2() }));
403
+
404
+ llm
405
+ .command("set-request-stuck-ms-v2 <ms>")
406
+ .description("Set request stuck threshold (V2)")
407
+ .action((ms) =>
408
+ tryRun(() => {
409
+ setRequestStuckMsV2(Number(ms));
410
+ out({ requestStuckMs: getRequestStuckMsV2() });
411
+ }),
412
+ );
413
+
414
+ llm
415
+ .command("active-profile-count-v2 <ownerId>")
416
+ .description("Active profile count for owner (V2)")
417
+ .action((ownerId) =>
418
+ out({ ownerId, count: getActiveProfileCountV2(ownerId) }),
419
+ );
420
+
421
+ llm
422
+ .command("pending-request-count-v2 <profileId>")
423
+ .description("Pending request count for profile (V2)")
424
+ .action((profileId) =>
425
+ out({ profileId, count: getPendingRequestCountV2(profileId) }),
426
+ );
427
+
428
+ llm
429
+ .command("register-profile-v2 <id>")
430
+ .description("Register a V2 profile")
431
+ .requiredOption("-o, --owner <id>", "owner id")
432
+ .requiredOption("-p, --provider <name>", "provider name")
433
+ .option("-m, --model <name>", "model name", "default")
434
+ .action((id, opts) =>
435
+ tryRun(() =>
436
+ out(
437
+ registerProfileV2(id, {
438
+ ownerId: opts.owner,
439
+ provider: opts.provider,
440
+ model: opts.model,
441
+ }),
442
+ ),
443
+ ),
444
+ );
445
+
446
+ llm
447
+ .command("get-profile-v2 <id>")
448
+ .description("Get a V2 profile")
449
+ .action((id) => out(getProfileV2(id)));
450
+
451
+ llm
452
+ .command("list-profiles-v2")
453
+ .description("List V2 profiles")
454
+ .option("-o, --owner <id>", "filter by owner")
455
+ .option("-s, --status <status>", "filter by status")
456
+ .option("-p, --provider <name>", "filter by provider")
457
+ .action((opts) =>
458
+ out(
459
+ listProfilesV2({
460
+ ownerId: opts.owner,
461
+ status: opts.status,
462
+ provider: opts.provider,
463
+ }),
464
+ ),
465
+ );
466
+
467
+ llm
468
+ .command("set-profile-status-v2 <id> <next>")
469
+ .description("Set V2 profile status")
470
+ .action((id, next) => tryRun(() => out(setProfileStatusV2(id, next))));
471
+
472
+ llm
473
+ .command("activate-profile-v2 <id>")
474
+ .description("Activate a V2 profile")
475
+ .action((id) => tryRun(() => out(activateProfileV2(id))));
476
+
477
+ llm
478
+ .command("suspend-profile-v2 <id>")
479
+ .description("Suspend a V2 profile")
480
+ .action((id) => tryRun(() => out(suspendProfileV2(id))));
481
+
482
+ llm
483
+ .command("retire-profile-v2 <id>")
484
+ .description("Retire a V2 profile")
485
+ .action((id) => tryRun(() => out(retireProfileV2(id))));
486
+
487
+ llm
488
+ .command("touch-profile-v2 <id>")
489
+ .description("Touch a V2 profile")
490
+ .action((id) => tryRun(() => out(touchProfileV2(id))));
491
+
492
+ llm
493
+ .command("create-request-v2 <id>")
494
+ .description("Create a V2 request")
495
+ .requiredOption("-p, --profile <id>", "profile id")
496
+ .option("-k, --kind <kind>", "request kind", "completion")
497
+ .action((id, opts) =>
498
+ tryRun(() =>
499
+ out(createRequestV2(id, { profileId: opts.profile, kind: opts.kind })),
500
+ ),
501
+ );
502
+
503
+ llm
504
+ .command("get-request-v2 <id>")
505
+ .description("Get a V2 request")
506
+ .action((id) => out(getRequestV2(id)));
507
+
508
+ llm
509
+ .command("list-requests-v2")
510
+ .description("List V2 requests")
511
+ .option("-p, --profile <id>", "filter by profile")
512
+ .option("-s, --status <status>", "filter by status")
513
+ .action((opts) =>
514
+ out(listRequestsV2({ profileId: opts.profile, status: opts.status })),
515
+ );
516
+
517
+ llm
518
+ .command("set-request-status-v2 <id> <next>")
519
+ .description("Set V2 request status")
520
+ .action((id, next) => tryRun(() => out(setRequestStatusV2(id, next))));
521
+
522
+ llm
523
+ .command("start-request-v2 <id>")
524
+ .description("Start a V2 request")
525
+ .action((id) => tryRun(() => out(startRequestV2(id))));
526
+
527
+ llm
528
+ .command("complete-request-v2 <id>")
529
+ .description("Complete a V2 request")
530
+ .action((id) => tryRun(() => out(completeRequestV2(id))));
531
+
532
+ llm
533
+ .command("fail-request-v2 <id>")
534
+ .description("Fail a V2 request")
535
+ .action((id) => tryRun(() => out(failRequestV2(id))));
536
+
537
+ llm
538
+ .command("cancel-request-v2 <id>")
539
+ .description("Cancel a V2 request")
540
+ .action((id) => tryRun(() => out(cancelRequestV2(id))));
541
+
542
+ llm
543
+ .command("auto-suspend-idle-profiles-v2")
544
+ .description("Auto-suspend idle V2 profiles")
545
+ .action(() => out(autoSuspendIdleProfilesV2()));
546
+
547
+ llm
548
+ .command("auto-fail-stuck-requests-v2")
549
+ .description("Auto-fail stuck V2 requests")
550
+ .action(() => out(autoFailStuckRequestsV2()));
288
551
  }