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
@@ -29,6 +29,28 @@ import {
29
29
  listPools,
30
30
  destroyPool,
31
31
  getFederationHardeningStats,
32
+ // V2 (Phase 58)
33
+ NODE_STATUS_V2,
34
+ FED_DEFAULT_FAILURE_THRESHOLD,
35
+ FED_DEFAULT_HALF_OPEN_COOLDOWN_MS,
36
+ FED_DEFAULT_UNHEALTHY_THRESHOLD,
37
+ FED_DEFAULT_MAX_ACTIVE_NODES,
38
+ setFailureThreshold,
39
+ getFailureThreshold,
40
+ setHalfOpenCooldownMs,
41
+ getHalfOpenCooldownMs,
42
+ setUnhealthyThreshold,
43
+ getUnhealthyThreshold,
44
+ setMaxActiveNodes,
45
+ getMaxActiveNodes,
46
+ getActiveNodeCount,
47
+ registerNodeV2,
48
+ getNodeStatusV2,
49
+ setNodeStatusV2,
50
+ recordHealthCheckV2,
51
+ tripCircuit,
52
+ autoIsolateUnhealthyNodes,
53
+ getFederationHardeningStatsV2,
32
54
  } from "../lib/federation-hardening.js";
33
55
 
34
56
  function _dbFromCtx(cmd) {
@@ -423,5 +445,266 @@ export function registerFederationCommand(program) {
423
445
  );
424
446
  });
425
447
 
448
+ /* ── V2 (Phase 58) ──────────────────────────────── */
449
+
450
+ fed
451
+ .command("node-statuses-v2")
452
+ .description("List V2 node lifecycle statuses")
453
+ .option("--json", "JSON output")
454
+ .action((opts) => {
455
+ const statuses = Object.values(NODE_STATUS_V2);
456
+ if (opts.json) return console.log(JSON.stringify(statuses, null, 2));
457
+ for (const s of statuses) console.log(` ${s}`);
458
+ });
459
+
460
+ fed
461
+ .command("default-failure-threshold")
462
+ .description("Default circuit-breaker failure threshold")
463
+ .option("--json", "JSON output")
464
+ .action((opts) => {
465
+ if (opts.json)
466
+ return console.log(JSON.stringify(FED_DEFAULT_FAILURE_THRESHOLD));
467
+ console.log(FED_DEFAULT_FAILURE_THRESHOLD);
468
+ });
469
+
470
+ fed
471
+ .command("failure-threshold")
472
+ .description("Current failure threshold")
473
+ .option("--json", "JSON output")
474
+ .action((opts) => {
475
+ const n = getFailureThreshold();
476
+ if (opts.json) return console.log(JSON.stringify(n));
477
+ console.log(n);
478
+ });
479
+
480
+ fed
481
+ .command("set-failure-threshold <n>")
482
+ .description("Set failure threshold (positive integer)")
483
+ .option("--json", "JSON output")
484
+ .action((n, opts) => {
485
+ setFailureThreshold(Number(n));
486
+ const out = { failureThreshold: getFailureThreshold() };
487
+ if (opts.json) return console.log(JSON.stringify(out, null, 2));
488
+ console.log(`failureThreshold = ${out.failureThreshold}`);
489
+ });
490
+
491
+ fed
492
+ .command("default-half-open-cooldown-ms")
493
+ .description("Default half-open cooldown in ms")
494
+ .option("--json", "JSON output")
495
+ .action((opts) => {
496
+ if (opts.json)
497
+ return console.log(JSON.stringify(FED_DEFAULT_HALF_OPEN_COOLDOWN_MS));
498
+ console.log(FED_DEFAULT_HALF_OPEN_COOLDOWN_MS);
499
+ });
500
+
501
+ fed
502
+ .command("half-open-cooldown-ms")
503
+ .description("Current half-open cooldown in ms")
504
+ .option("--json", "JSON output")
505
+ .action((opts) => {
506
+ const n = getHalfOpenCooldownMs();
507
+ if (opts.json) return console.log(JSON.stringify(n));
508
+ console.log(n);
509
+ });
510
+
511
+ fed
512
+ .command("set-half-open-cooldown-ms <ms>")
513
+ .description("Set half-open cooldown (positive integer ms)")
514
+ .option("--json", "JSON output")
515
+ .action((ms, opts) => {
516
+ setHalfOpenCooldownMs(Number(ms));
517
+ const out = { halfOpenCooldownMs: getHalfOpenCooldownMs() };
518
+ if (opts.json) return console.log(JSON.stringify(out, null, 2));
519
+ console.log(`halfOpenCooldownMs = ${out.halfOpenCooldownMs}`);
520
+ });
521
+
522
+ fed
523
+ .command("default-unhealthy-threshold")
524
+ .description("Default consecutive-unhealthy isolation threshold")
525
+ .option("--json", "JSON output")
526
+ .action((opts) => {
527
+ if (opts.json)
528
+ return console.log(JSON.stringify(FED_DEFAULT_UNHEALTHY_THRESHOLD));
529
+ console.log(FED_DEFAULT_UNHEALTHY_THRESHOLD);
530
+ });
531
+
532
+ fed
533
+ .command("unhealthy-threshold")
534
+ .description("Current consecutive-unhealthy threshold")
535
+ .option("--json", "JSON output")
536
+ .action((opts) => {
537
+ const n = getUnhealthyThreshold();
538
+ if (opts.json) return console.log(JSON.stringify(n));
539
+ console.log(n);
540
+ });
541
+
542
+ fed
543
+ .command("set-unhealthy-threshold <n>")
544
+ .description("Set consecutive-unhealthy threshold")
545
+ .option("--json", "JSON output")
546
+ .action((n, opts) => {
547
+ setUnhealthyThreshold(Number(n));
548
+ const out = { unhealthyThreshold: getUnhealthyThreshold() };
549
+ if (opts.json) return console.log(JSON.stringify(out, null, 2));
550
+ console.log(`unhealthyThreshold = ${out.unhealthyThreshold}`);
551
+ });
552
+
553
+ fed
554
+ .command("default-max-active-nodes")
555
+ .description("Default max active nodes cap")
556
+ .option("--json", "JSON output")
557
+ .action((opts) => {
558
+ if (opts.json)
559
+ return console.log(JSON.stringify(FED_DEFAULT_MAX_ACTIVE_NODES));
560
+ console.log(FED_DEFAULT_MAX_ACTIVE_NODES);
561
+ });
562
+
563
+ fed
564
+ .command("max-active-nodes")
565
+ .description("Current max active nodes cap")
566
+ .option("--json", "JSON output")
567
+ .action((opts) => {
568
+ const n = getMaxActiveNodes();
569
+ if (opts.json) return console.log(JSON.stringify(n));
570
+ console.log(n);
571
+ });
572
+
573
+ fed
574
+ .command("active-node-count")
575
+ .description("Number of currently ACTIVE nodes")
576
+ .option("--json", "JSON output")
577
+ .action((opts) => {
578
+ const n = getActiveNodeCount();
579
+ if (opts.json) return console.log(JSON.stringify(n));
580
+ console.log(n);
581
+ });
582
+
583
+ fed
584
+ .command("set-max-active-nodes <n>")
585
+ .description("Set max active nodes cap")
586
+ .option("--json", "JSON output")
587
+ .action((n, opts) => {
588
+ setMaxActiveNodes(Number(n));
589
+ const out = { maxActiveNodes: getMaxActiveNodes() };
590
+ if (opts.json) return console.log(JSON.stringify(out, null, 2));
591
+ console.log(`maxActiveNodes = ${out.maxActiveNodes}`);
592
+ });
593
+
594
+ fed
595
+ .command("register-v2 <node-id>")
596
+ .description("Register a node with V2 lifecycle tracking")
597
+ .option("-m, --metadata <json>", "JSON metadata")
598
+ .option("--json", "JSON output")
599
+ .action((nodeId, opts) => {
600
+ const db = _dbFromCtx(fed);
601
+ const metadata = opts.metadata ? JSON.parse(opts.metadata) : undefined;
602
+ const r = registerNodeV2(db, { nodeId, metadata });
603
+ if (opts.json) return console.log(JSON.stringify(r, null, 2));
604
+ console.log(`Registered ${nodeId} (status: ${r.status})`);
605
+ });
606
+
607
+ fed
608
+ .command("node-status-v2 <node-id>")
609
+ .description("Get V2 node status")
610
+ .option("--json", "JSON output")
611
+ .action((nodeId, opts) => {
612
+ const r = getNodeStatusV2(nodeId);
613
+ if (opts.json) return console.log(JSON.stringify(r, null, 2));
614
+ if (!r) return console.log("(not found)");
615
+ console.log(`${nodeId}: ${r.status}${r.reason ? ` — ${r.reason}` : ""}`);
616
+ });
617
+
618
+ fed
619
+ .command("set-node-status-v2 <node-id> <status>")
620
+ .description("Transition node to a new status")
621
+ .option("-r, --reason <reason>")
622
+ .option("-m, --metadata <json>")
623
+ .option("--json", "JSON output")
624
+ .action((nodeId, status, opts) => {
625
+ const db = _dbFromCtx(fed);
626
+ const patch = {};
627
+ if (opts.reason !== undefined) patch.reason = opts.reason;
628
+ if (opts.metadata !== undefined)
629
+ patch.metadata = JSON.parse(opts.metadata);
630
+ const r = setNodeStatusV2(db, nodeId, status, patch);
631
+ if (opts.json) return console.log(JSON.stringify(r, null, 2));
632
+ console.log(`${nodeId} → ${r.status}`);
633
+ });
634
+
635
+ fed
636
+ .command("record-health-v2 <node-id>")
637
+ .description("Record a V2 health check (throws on invalid input)")
638
+ .option(
639
+ "-t, --type <checkType>",
640
+ "heartbeat|latency|success_rate|cpu_usage|memory_usage",
641
+ "heartbeat",
642
+ )
643
+ .option(
644
+ "-s, --status <status>",
645
+ "healthy|degraded|unhealthy|unknown",
646
+ "healthy",
647
+ )
648
+ .option("-m, --metrics <json>", "Optional metrics JSON")
649
+ .option("--json", "JSON output")
650
+ .action((nodeId, opts) => {
651
+ const db = _dbFromCtx(fed);
652
+ const metrics = opts.metrics ? JSON.parse(opts.metrics) : undefined;
653
+ const r = recordHealthCheckV2(db, {
654
+ nodeId,
655
+ checkType: opts.type,
656
+ status: opts.status,
657
+ metrics,
658
+ });
659
+ if (opts.json) return console.log(JSON.stringify(r, null, 2));
660
+ console.log(`recorded check ${r.checkId}`);
661
+ });
662
+
663
+ fed
664
+ .command("trip-circuit <node-id>")
665
+ .description("Force-trip a circuit breaker (closed/half_open → open)")
666
+ .option("--json", "JSON output")
667
+ .action((nodeId, opts) => {
668
+ const db = _dbFromCtx(fed);
669
+ const r = tripCircuit(db, nodeId);
670
+ if (opts.json) return console.log(JSON.stringify(r, null, 2));
671
+ console.log(`${nodeId} circuit → ${r.state}`);
672
+ });
673
+
674
+ fed
675
+ .command("auto-isolate-unhealthy")
676
+ .description(
677
+ "Bulk-isolate ACTIVE nodes with N consecutive UNHEALTHY checks",
678
+ )
679
+ .option("--json", "JSON output")
680
+ .action((opts) => {
681
+ const db = _dbFromCtx(fed);
682
+ const r = autoIsolateUnhealthyNodes(db);
683
+ if (opts.json) return console.log(JSON.stringify(r, null, 2));
684
+ console.log(`Isolated ${r.length} node(s)`);
685
+ for (const n of r) console.log(` ${n.node_id}`);
686
+ });
687
+
688
+ fed
689
+ .command("stats-v2")
690
+ .description("V2 federation hardening statistics")
691
+ .option("--json", "JSON output")
692
+ .action((opts) => {
693
+ const db = _dbFromCtx(fed);
694
+ const s = getFederationHardeningStatsV2(db);
695
+ if (opts.json) return console.log(JSON.stringify(s, null, 2));
696
+ console.log(
697
+ `Nodes: ${s.totalNodes} (active=${s.activeNodes}, isolated=${s.isolatedNodes})`,
698
+ );
699
+ console.log(`Circuits: ${s.totalCircuits}`);
700
+ for (const [state, count] of Object.entries(s.circuitsByState)) {
701
+ if (count > 0) console.log(` ${state.padEnd(10)} ${count}`);
702
+ }
703
+ console.log(`Health checks: ${s.totalHealthChecks}`);
704
+ console.log(
705
+ `config: failureThreshold=${s.failureThreshold} halfOpenCooldownMs=${s.halfOpenCooldownMs} unhealthyThreshold=${s.unhealthyThreshold} maxActiveNodes=${s.maxActiveNodes}`,
706
+ );
707
+ });
708
+
426
709
  program.addCommand(fed);
427
710
  }
@@ -24,8 +24,49 @@ import {
24
24
  detectLanguage,
25
25
  getTranslationStats,
26
26
  getProtocolFusionStats,
27
+ BRIDGE_MATURITY_V2,
28
+ TRANSLATION_RUN_V2,
29
+ getMaxActiveBridgesPerOperator,
30
+ setMaxActiveBridgesPerOperator,
31
+ getMaxRunningTranslationsPerBridge,
32
+ setMaxRunningTranslationsPerBridge,
33
+ getBridgeIdleMs,
34
+ setBridgeIdleMs,
35
+ getTranslationStuckMs,
36
+ setTranslationStuckMs,
37
+ getActiveBridgeCount,
38
+ getRunningTranslationCount,
39
+ registerBridgeV2,
40
+ getBridgeV2,
41
+ listBridgesV2,
42
+ setBridgeMaturityV2,
43
+ activateBridge,
44
+ degradeBridge,
45
+ deprecateBridge,
46
+ retireBridge,
47
+ touchBridgeUsage,
48
+ enqueueTranslationV2,
49
+ getTranslationV2,
50
+ listTranslationsV2,
51
+ setTranslationStatusV2,
52
+ startTranslation,
53
+ succeedTranslation,
54
+ failTranslation,
55
+ cancelTranslation,
56
+ autoRetireIdleBridges,
57
+ autoFailStuckRunningTranslations,
58
+ getProtocolFusionStatsV2,
27
59
  } from "../lib/protocol-fusion.js";
28
60
 
61
+ function _parseJson(s) {
62
+ if (!s) return undefined;
63
+ try {
64
+ return JSON.parse(s);
65
+ } catch {
66
+ throw new Error(`invalid JSON: ${s}`);
67
+ }
68
+ }
69
+
29
70
  function _dbFromCtx(cmd) {
30
71
  const root = cmd?.parent?.parent ?? cmd?.parent;
31
72
  return root?._db;
@@ -328,5 +369,222 @@ export function registerFusionCommand(program) {
328
369
  );
329
370
  });
330
371
 
372
+ /* ── V2 Surface (Phase 72-73) ─────────────────────────── */
373
+
374
+ fu.command("bridge-maturities-v2")
375
+ .description("List BRIDGE_MATURITY_V2 enum values")
376
+ .action(() => {
377
+ for (const v of Object.values(BRIDGE_MATURITY_V2)) console.log(` ${v}`);
378
+ });
379
+
380
+ fu.command("translation-runs-v2")
381
+ .description("List TRANSLATION_RUN_V2 enum values")
382
+ .action(() => {
383
+ for (const v of Object.values(TRANSLATION_RUN_V2)) console.log(` ${v}`);
384
+ });
385
+
386
+ fu.command("max-active-bridges-per-operator")
387
+ .description("Get current max-active-bridges-per-operator cap")
388
+ .action(() => console.log(getMaxActiveBridgesPerOperator()));
389
+ fu.command("set-max-active-bridges-per-operator <n>")
390
+ .description("Set max-active-bridges-per-operator cap")
391
+ .action((n) => console.log(setMaxActiveBridgesPerOperator(Number(n))));
392
+
393
+ fu.command("max-running-translations-per-bridge")
394
+ .description("Get current max-running-translations-per-bridge cap")
395
+ .action(() => console.log(getMaxRunningTranslationsPerBridge()));
396
+ fu.command("set-max-running-translations-per-bridge <n>")
397
+ .description("Set max-running-translations-per-bridge cap")
398
+ .action((n) => console.log(setMaxRunningTranslationsPerBridge(Number(n))));
399
+
400
+ fu.command("bridge-idle-ms")
401
+ .description("Get current bridge-idle-ms threshold")
402
+ .action(() => console.log(getBridgeIdleMs()));
403
+ fu.command("set-bridge-idle-ms <n>")
404
+ .description("Set bridge-idle-ms threshold")
405
+ .action((n) => console.log(setBridgeIdleMs(Number(n))));
406
+
407
+ fu.command("translation-stuck-ms")
408
+ .description("Get current translation-stuck-ms threshold")
409
+ .action(() => console.log(getTranslationStuckMs()));
410
+ fu.command("set-translation-stuck-ms <n>")
411
+ .description("Set translation-stuck-ms threshold")
412
+ .action((n) => console.log(setTranslationStuckMs(Number(n))));
413
+
414
+ fu.command("active-bridge-count")
415
+ .description(
416
+ "Count non-retired, non-provisional bridges (optionally by operator)",
417
+ )
418
+ .option("-o, --operator <operator>", "scope to operator")
419
+ .action((opts) => console.log(getActiveBridgeCount(opts.operator)));
420
+
421
+ fu.command("running-translation-count")
422
+ .description("Count RUNNING translations (optionally by bridge)")
423
+ .option("-b, --bridge <bridge>", "scope to bridge")
424
+ .action((opts) => console.log(getRunningTranslationCount(opts.bridge)));
425
+
426
+ fu.command("register-bridge-v2 <bridge-id>")
427
+ .description("Register V2 bridge (provisional by default)")
428
+ .requiredOption("-o, --operator <operator>", "operator id")
429
+ .requiredOption("-s, --source <protocol>", "source protocol")
430
+ .requiredOption("-t, --target <protocol>", "target protocol")
431
+ .option(
432
+ "-i, --initial <status>",
433
+ "initial status",
434
+ BRIDGE_MATURITY_V2.PROVISIONAL,
435
+ )
436
+ .option("--metadata <json>", "metadata JSON")
437
+ .action((id, opts) => {
438
+ const b = registerBridgeV2({
439
+ id,
440
+ operator: opts.operator,
441
+ sourceProtocol: opts.source,
442
+ targetProtocol: opts.target,
443
+ initialStatus: opts.initial,
444
+ metadata: _parseJson(opts.metadata),
445
+ });
446
+ console.log(JSON.stringify(b, null, 2));
447
+ });
448
+
449
+ fu.command("bridge-v2 <bridge-id>")
450
+ .description("Show V2 bridge state")
451
+ .action((id) => {
452
+ const b = getBridgeV2(id);
453
+ if (!b) return console.error(`bridge ${id} not found`);
454
+ console.log(JSON.stringify(b, null, 2));
455
+ });
456
+
457
+ fu.command("list-bridges-v2")
458
+ .description("List V2 bridges")
459
+ .option("-o, --operator <operator>", "filter by operator")
460
+ .option("-s, --status <status>", "filter by status")
461
+ .action((opts) => {
462
+ console.log(JSON.stringify(listBridgesV2(opts), null, 2));
463
+ });
464
+
465
+ fu.command("set-bridge-maturity-v2 <bridge-id> <status>")
466
+ .description("Transition V2 bridge maturity")
467
+ .option("-r, --reason <reason>", "transition reason")
468
+ .option("--metadata <json>", "metadata patch JSON")
469
+ .action((id, status, opts) => {
470
+ const b = setBridgeMaturityV2(id, status, {
471
+ reason: opts.reason,
472
+ metadata: _parseJson(opts.metadata),
473
+ });
474
+ console.log(JSON.stringify(b, null, 2));
475
+ });
476
+
477
+ for (const [name, fn] of [
478
+ ["activate-bridge", activateBridge],
479
+ ["degrade-bridge", degradeBridge],
480
+ ["deprecate-bridge", deprecateBridge],
481
+ ["retire-bridge", retireBridge],
482
+ ]) {
483
+ fu.command(`${name} <bridge-id>`)
484
+ .description(`Shortcut for ${name.replace("-bridge", "")} transition`)
485
+ .option("-r, --reason <reason>", "transition reason")
486
+ .action((id, opts) => {
487
+ const b = fn(id, { reason: opts.reason });
488
+ console.log(JSON.stringify(b, null, 2));
489
+ });
490
+ }
491
+
492
+ fu.command("touch-bridge-usage <bridge-id>")
493
+ .description("Mark V2 bridge as used now (for idle auto-retire)")
494
+ .action((id) => {
495
+ const b = touchBridgeUsage(id);
496
+ console.log(JSON.stringify(b, null, 2));
497
+ });
498
+
499
+ fu.command("enqueue-translation-v2 <translation-id>")
500
+ .description("Enqueue a V2 translation run")
501
+ .requiredOption("-b, --bridge <bridge>", "bridge id")
502
+ .requiredOption("-t, --target <lang>", "target language")
503
+ .requiredOption("-x, --text <text>", "text to translate")
504
+ .option("-s, --source <lang>", "source language", "auto")
505
+ .option("--metadata <json>", "metadata JSON")
506
+ .action((id, opts) => {
507
+ const t = enqueueTranslationV2({
508
+ id,
509
+ bridgeId: opts.bridge,
510
+ targetLang: opts.target,
511
+ text: opts.text,
512
+ sourceLang: opts.source,
513
+ metadata: _parseJson(opts.metadata),
514
+ });
515
+ console.log(JSON.stringify(t, null, 2));
516
+ });
517
+
518
+ fu.command("translation-v2 <translation-id>")
519
+ .description("Show V2 translation state")
520
+ .action((id) => {
521
+ const t = getTranslationV2(id);
522
+ if (!t) return console.error(`translation ${id} not found`);
523
+ console.log(JSON.stringify(t, null, 2));
524
+ });
525
+
526
+ fu.command("list-translations-v2")
527
+ .description("List V2 translations")
528
+ .option("-b, --bridge <bridge>", "filter by bridge")
529
+ .option("-s, --status <status>", "filter by status")
530
+ .action((opts) => {
531
+ console.log(JSON.stringify(listTranslationsV2(opts), null, 2));
532
+ });
533
+
534
+ fu.command("set-translation-status-v2 <translation-id> <status>")
535
+ .description("Transition V2 translation status")
536
+ .option("-r, --reason <reason>", "transition reason")
537
+ .option("--metadata <json>", "metadata patch JSON")
538
+ .option("--result <json>", "result JSON (on success)")
539
+ .action((id, status, opts) => {
540
+ const t = setTranslationStatusV2(id, status, {
541
+ reason: opts.reason,
542
+ metadata: _parseJson(opts.metadata),
543
+ result: _parseJson(opts.result),
544
+ });
545
+ console.log(JSON.stringify(t, null, 2));
546
+ });
547
+
548
+ for (const [name, fn] of [
549
+ ["start-translation", startTranslation],
550
+ ["succeed-translation", succeedTranslation],
551
+ ["fail-translation", failTranslation],
552
+ ["cancel-translation", cancelTranslation],
553
+ ]) {
554
+ fu.command(`${name} <translation-id>`)
555
+ .description(
556
+ `Shortcut for ${name.replace("-translation", "")} transition`,
557
+ )
558
+ .option("-r, --reason <reason>", "transition reason")
559
+ .action((id, opts) => {
560
+ const t = fn(id, { reason: opts.reason });
561
+ console.log(JSON.stringify(t, null, 2));
562
+ });
563
+ }
564
+
565
+ fu.command("auto-retire-idle-bridges")
566
+ .description(
567
+ "Bulk-retire ACTIVE/DEGRADED/DEPRECATED bridges whose lastUsedAt is older than bridgeIdleMs",
568
+ )
569
+ .action(() => {
570
+ const flipped = autoRetireIdleBridges();
571
+ console.log(JSON.stringify({ flipped }, null, 2));
572
+ });
573
+
574
+ fu.command("auto-fail-stuck-running-translations")
575
+ .description(
576
+ "Bulk-fail RUNNING translations whose startedAt is older than translationStuckMs",
577
+ )
578
+ .action(() => {
579
+ const flipped = autoFailStuckRunningTranslations();
580
+ console.log(JSON.stringify({ flipped }, null, 2));
581
+ });
582
+
583
+ fu.command("stats-v2")
584
+ .description("Show V2 stats with all-enum zero-initialized counters")
585
+ .action(() => {
586
+ console.log(JSON.stringify(getProtocolFusionStatsV2(), null, 2));
587
+ });
588
+
331
589
  program.addCommand(fu);
332
590
  }