chainlesschain 0.51.0 → 0.81.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 (70) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/.build-hash +1 -1
  3. package/src/assets/web-panel/assets/{AppLayout-Rvi759IS.js → AppLayout-6SPt_8Y_.js} +1 -1
  4. package/src/assets/web-panel/assets/{Dashboard-DBhFxXYQ.js → Dashboard-Br7kCwKJ.js} +2 -2
  5. package/src/assets/web-panel/assets/Dashboard-CKeMmCoT.css +1 -0
  6. package/src/assets/web-panel/assets/{index-uL0cZ8N_.js → index-tN-8TosE.js} +2 -2
  7. package/src/assets/web-panel/index.html +2 -2
  8. package/src/commands/a2a.js +380 -0
  9. package/src/commands/agent-network.js +785 -0
  10. package/src/commands/automation.js +654 -0
  11. package/src/commands/bi.js +348 -0
  12. package/src/commands/crosschain.js +218 -0
  13. package/src/commands/dao.js +565 -0
  14. package/src/commands/did-v2.js +620 -0
  15. package/src/commands/dlp.js +341 -0
  16. package/src/commands/economy.js +578 -0
  17. package/src/commands/evolution.js +391 -0
  18. package/src/commands/evomap.js +394 -0
  19. package/src/commands/federation.js +283 -0
  20. package/src/commands/hmemory.js +442 -0
  21. package/src/commands/inference.js +318 -0
  22. package/src/commands/lowcode.js +356 -0
  23. package/src/commands/marketplace.js +256 -0
  24. package/src/commands/perf.js +433 -0
  25. package/src/commands/pipeline.js +449 -0
  26. package/src/commands/plugin-ecosystem.js +517 -0
  27. package/src/commands/privacy.js +321 -0
  28. package/src/commands/reputation.js +261 -0
  29. package/src/commands/sandbox.js +401 -0
  30. package/src/commands/siem.js +246 -0
  31. package/src/commands/sla.js +259 -0
  32. package/src/commands/social.js +311 -0
  33. package/src/commands/sso.js +798 -0
  34. package/src/commands/stress.js +230 -0
  35. package/src/commands/terraform.js +245 -0
  36. package/src/commands/workflow.js +320 -0
  37. package/src/commands/zkp.js +562 -1
  38. package/src/index.js +21 -0
  39. package/src/lib/a2a-protocol.js +451 -0
  40. package/src/lib/agent-economy.js +479 -0
  41. package/src/lib/agent-network.js +1121 -0
  42. package/src/lib/app-builder.js +239 -0
  43. package/src/lib/automation-engine.js +948 -0
  44. package/src/lib/bi-engine.js +338 -0
  45. package/src/lib/cross-chain.js +345 -0
  46. package/src/lib/dao-governance.js +569 -0
  47. package/src/lib/did-v2-manager.js +1127 -0
  48. package/src/lib/dlp-engine.js +389 -0
  49. package/src/lib/evolution-system.js +453 -0
  50. package/src/lib/evomap-federation.js +177 -0
  51. package/src/lib/evomap-governance.js +276 -0
  52. package/src/lib/federation-hardening.js +259 -0
  53. package/src/lib/hierarchical-memory.js +481 -0
  54. package/src/lib/inference-network.js +330 -0
  55. package/src/lib/perf-tuning.js +734 -0
  56. package/src/lib/pipeline-orchestrator.js +928 -0
  57. package/src/lib/plugin-ecosystem.js +1109 -0
  58. package/src/lib/privacy-computing.js +427 -0
  59. package/src/lib/reputation-optimizer.js +299 -0
  60. package/src/lib/sandbox-v2.js +306 -0
  61. package/src/lib/siem-exporter.js +333 -0
  62. package/src/lib/skill-marketplace.js +325 -0
  63. package/src/lib/sla-manager.js +275 -0
  64. package/src/lib/social-graph-analytics.js +707 -0
  65. package/src/lib/sso-manager.js +841 -0
  66. package/src/lib/stress-tester.js +330 -0
  67. package/src/lib/terraform-manager.js +363 -0
  68. package/src/lib/workflow-engine.js +454 -1
  69. package/src/lib/zkp-engine.js +523 -20
  70. package/src/assets/web-panel/assets/Dashboard-BS-tzGNj.css +0 -1
@@ -21,6 +21,31 @@ import {
21
21
  recordContribution,
22
22
  getContributions,
23
23
  distributeRevenue,
24
+ // Phase 85 V2
25
+ PAYMENT_TYPE,
26
+ CHANNEL_STATUS,
27
+ RESOURCE_TYPE,
28
+ NFT_STATUS,
29
+ priceServiceV2,
30
+ getPriceModel,
31
+ payV2,
32
+ openChannelV2,
33
+ activateChannel,
34
+ initiateSettlement,
35
+ closeChannelV2,
36
+ disputeChannel,
37
+ listChannelsV2,
38
+ listResourceV2,
39
+ mintNFTV2,
40
+ listNFT,
41
+ buyNFT,
42
+ burnNFT,
43
+ getNFTStatus,
44
+ recordTaskContribution,
45
+ getTaskContributions,
46
+ distributeRevenueV2,
47
+ listDistributions,
48
+ getEconomyStatsV2,
24
49
  } from "../lib/agent-economy.js";
25
50
 
26
51
  export function registerEconomyCommand(program) {
@@ -372,4 +397,557 @@ export function registerEconomyCommand(program) {
372
397
  process.exit(1);
373
398
  }
374
399
  });
400
+
401
+ // ═════════════════════════════════════════════════════════════════
402
+ // Phase 85 — Agent Economy 2.0 subcommands
403
+ // ═════════════════════════════════════════════════════════════════
404
+
405
+ economy
406
+ .command("payment-types")
407
+ .description("List PAYMENT_TYPE enum values (Phase 85)")
408
+ .option("--json", "Output as JSON")
409
+ .action((options) => {
410
+ const v = Object.values(PAYMENT_TYPE);
411
+ if (options.json) console.log(JSON.stringify(v, null, 2));
412
+ else v.forEach((x) => logger.log(` ${chalk.cyan(x)}`));
413
+ });
414
+
415
+ economy
416
+ .command("channel-statuses")
417
+ .description("List CHANNEL_STATUS enum values (Phase 85)")
418
+ .option("--json", "Output as JSON")
419
+ .action((options) => {
420
+ const v = Object.values(CHANNEL_STATUS);
421
+ if (options.json) console.log(JSON.stringify(v, null, 2));
422
+ else v.forEach((x) => logger.log(` ${chalk.cyan(x)}`));
423
+ });
424
+
425
+ economy
426
+ .command("resource-types")
427
+ .description("List RESOURCE_TYPE enum values (Phase 85)")
428
+ .option("--json", "Output as JSON")
429
+ .action((options) => {
430
+ const v = Object.values(RESOURCE_TYPE);
431
+ if (options.json) console.log(JSON.stringify(v, null, 2));
432
+ else v.forEach((x) => logger.log(` ${chalk.cyan(x)}`));
433
+ });
434
+
435
+ economy
436
+ .command("nft-statuses")
437
+ .description("List NFT_STATUS enum values (Phase 85)")
438
+ .option("--json", "Output as JSON")
439
+ .action((options) => {
440
+ const v = Object.values(NFT_STATUS);
441
+ if (options.json) console.log(JSON.stringify(v, null, 2));
442
+ else v.forEach((x) => logger.log(` ${chalk.cyan(x)}`));
443
+ });
444
+
445
+ economy
446
+ .command("price-v2")
447
+ .description("Set a service price with payment-type model (Phase 85)")
448
+ .argument("<service-id>", "Service ID")
449
+ .argument("<payment-type>", "per_call|per_token|per_minute|flat_rate")
450
+ .argument("<rate>", "Unit rate")
451
+ .option("--json", "Output as JSON")
452
+ .action(async (serviceId, paymentType, rate, options) => {
453
+ try {
454
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
455
+ const db = ctx.db.getDatabase();
456
+ const m = priceServiceV2(db, {
457
+ serviceId,
458
+ paymentType,
459
+ rate: parseFloat(rate),
460
+ });
461
+ if (options.json) console.log(JSON.stringify(m, null, 2));
462
+ else
463
+ logger.log(
464
+ `${chalk.green("✓")} priced ${chalk.cyan(serviceId)} as ${paymentType}@${rate}`,
465
+ );
466
+ await shutdown();
467
+ } catch (err) {
468
+ logger.error(`Failed: ${err.message}`);
469
+ process.exit(1);
470
+ }
471
+ });
472
+
473
+ economy
474
+ .command("price-get")
475
+ .description("Get a service's price model (Phase 85)")
476
+ .argument("<service-id>", "Service ID")
477
+ .option("--json", "Output as JSON")
478
+ .action(async (serviceId, options) => {
479
+ try {
480
+ await bootstrap({ verbose: program.opts().verbose });
481
+ const m = getPriceModel(serviceId);
482
+ if (options.json) console.log(JSON.stringify(m, null, 2));
483
+ else if (!m) logger.info("No price model.");
484
+ else
485
+ logger.log(
486
+ `${chalk.cyan(m.serviceId)} ${m.paymentType}@${chalk.yellow(m.rate)}`,
487
+ );
488
+ await shutdown();
489
+ } catch (err) {
490
+ logger.error(`Failed: ${err.message}`);
491
+ process.exit(1);
492
+ }
493
+ });
494
+
495
+ economy
496
+ .command("pay-v2")
497
+ .description(
498
+ "Pay for a priced service (computes amount from usage) (Phase 85)",
499
+ )
500
+ .argument("<from>", "From agent ID")
501
+ .argument("<to>", "To agent ID")
502
+ .argument("<service-id>", "Service ID")
503
+ .option("--tokens <n>", "Token count (for per_token)", parseInt)
504
+ .option("--minutes <n>", "Minute count (for per_minute)", parseFloat)
505
+ .option("--calls <n>", "Call count (for per_call)", parseInt)
506
+ .option("--json", "Output as JSON")
507
+ .action(async (from, to, serviceId, options) => {
508
+ try {
509
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
510
+ const db = ctx.db.getDatabase();
511
+ const r = payV2(db, {
512
+ fromAgentId: from,
513
+ toAgentId: to,
514
+ serviceId,
515
+ tokens: options.tokens,
516
+ minutes: options.minutes,
517
+ calls: options.calls,
518
+ });
519
+ if (options.json) console.log(JSON.stringify(r, null, 2));
520
+ else
521
+ logger.log(
522
+ `${chalk.green("✓")} paid ${chalk.yellow(r.amount)} via ${r.paymentType}`,
523
+ );
524
+ await shutdown();
525
+ } catch (err) {
526
+ logger.error(`Failed: ${err.message}`);
527
+ process.exit(1);
528
+ }
529
+ });
530
+
531
+ economy
532
+ .command("channel-open-v2")
533
+ .description("Open a two-sided channel (Phase 85)")
534
+ .argument("<party-a>", "Party A ID")
535
+ .argument("<party-b>", "Party B ID")
536
+ .option("--deposit-a <n>", "Deposit from party A", parseFloat)
537
+ .option("--deposit-b <n>", "Deposit from party B", parseFloat)
538
+ .option("--json", "Output as JSON")
539
+ .action(async (a, b, options) => {
540
+ try {
541
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
542
+ const db = ctx.db.getDatabase();
543
+ const ch = openChannelV2(db, {
544
+ partyA: a,
545
+ partyB: b,
546
+ depositA: options.depositA || 0,
547
+ depositB: options.depositB || 0,
548
+ });
549
+ if (options.json) console.log(JSON.stringify(ch, null, 2));
550
+ else
551
+ logger.log(
552
+ `${chalk.green("✓")} channel ${chalk.cyan(ch.id)} opened (${ch.balanceA}↔${ch.balanceB})`,
553
+ );
554
+ await shutdown();
555
+ } catch (err) {
556
+ logger.error(`Failed: ${err.message}`);
557
+ process.exit(1);
558
+ }
559
+ });
560
+
561
+ economy
562
+ .command("channel-activate")
563
+ .description("OPEN → ACTIVE (Phase 85)")
564
+ .argument("<id>", "Channel ID")
565
+ .option("--json", "Output as JSON")
566
+ .action(async (id, options) => {
567
+ try {
568
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
569
+ const db = ctx.db.getDatabase();
570
+ const r = activateChannel(db, id);
571
+ if (options.json) console.log(JSON.stringify(r, null, 2));
572
+ else logger.log(`${chalk.green("✓ Active")} ${chalk.cyan(id)}`);
573
+ await shutdown();
574
+ } catch (err) {
575
+ logger.error(`Failed: ${err.message}`);
576
+ process.exit(1);
577
+ }
578
+ });
579
+
580
+ economy
581
+ .command("channel-settle")
582
+ .description("ACTIVE → SETTLING with final balances (Phase 85)")
583
+ .argument("<id>", "Channel ID")
584
+ .requiredOption("--final-a <n>", "Final balance A", parseFloat)
585
+ .requiredOption("--final-b <n>", "Final balance B", parseFloat)
586
+ .option("--json", "Output as JSON")
587
+ .action(async (id, options) => {
588
+ try {
589
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
590
+ const db = ctx.db.getDatabase();
591
+ const r = initiateSettlement(db, id, {
592
+ finalBalanceA: options.finalA,
593
+ finalBalanceB: options.finalB,
594
+ });
595
+ if (options.json) console.log(JSON.stringify(r, null, 2));
596
+ else
597
+ logger.log(
598
+ `${chalk.green("✓ Settling")} ${chalk.cyan(id)} a=${r.balanceA} b=${r.balanceB}`,
599
+ );
600
+ await shutdown();
601
+ } catch (err) {
602
+ logger.error(`Failed: ${err.message}`);
603
+ process.exit(1);
604
+ }
605
+ });
606
+
607
+ economy
608
+ .command("channel-close-v2")
609
+ .description("Close channel and release locked funds (Phase 85)")
610
+ .argument("<id>", "Channel ID")
611
+ .option("--json", "Output as JSON")
612
+ .action(async (id, options) => {
613
+ try {
614
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
615
+ const db = ctx.db.getDatabase();
616
+ const r = closeChannelV2(db, id);
617
+ if (options.json) console.log(JSON.stringify(r, null, 2));
618
+ else logger.log(`${chalk.green("✓ Closed")} ${chalk.cyan(id)}`);
619
+ await shutdown();
620
+ } catch (err) {
621
+ logger.error(`Failed: ${err.message}`);
622
+ process.exit(1);
623
+ }
624
+ });
625
+
626
+ economy
627
+ .command("channel-dispute")
628
+ .description("Mark channel DISPUTED (Phase 85)")
629
+ .argument("<id>", "Channel ID")
630
+ .option("--reason <r>", "Dispute reason", "dispute")
631
+ .option("--json", "Output as JSON")
632
+ .action(async (id, options) => {
633
+ try {
634
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
635
+ const db = ctx.db.getDatabase();
636
+ const r = disputeChannel(db, id, options.reason);
637
+ if (options.json) console.log(JSON.stringify(r, null, 2));
638
+ else
639
+ logger.log(
640
+ `${chalk.red("⚠ Disputed")} ${chalk.cyan(id)} reason=${options.reason}`,
641
+ );
642
+ await shutdown();
643
+ } catch (err) {
644
+ logger.error(`Failed: ${err.message}`);
645
+ process.exit(1);
646
+ }
647
+ });
648
+
649
+ economy
650
+ .command("channels-v2")
651
+ .description("List channels with optional status/party filter (Phase 85)")
652
+ .option("-s, --status <s>", "Filter by status")
653
+ .option("-p, --party <id>", "Filter by party")
654
+ .option("--json", "Output as JSON")
655
+ .action(async (options) => {
656
+ try {
657
+ await bootstrap({ verbose: program.opts().verbose });
658
+ const r = listChannelsV2({
659
+ status: options.status,
660
+ party: options.party,
661
+ });
662
+ if (options.json) console.log(JSON.stringify(r, null, 2));
663
+ else if (r.length === 0) logger.info("No channels.");
664
+ else
665
+ r.forEach((c) =>
666
+ logger.log(
667
+ ` ${chalk.cyan(c.id)} ${c.partyA}↔${c.partyB} ${chalk.yellow(c.status)}`,
668
+ ),
669
+ );
670
+ await shutdown();
671
+ } catch (err) {
672
+ logger.error(`Failed: ${err.message}`);
673
+ process.exit(1);
674
+ }
675
+ });
676
+
677
+ economy
678
+ .command("market-list-v2")
679
+ .description("List a resource with validated RESOURCE_TYPE (Phase 85)")
680
+ .argument("<seller>", "Seller ID")
681
+ .argument("<resource-type>", "compute|storage|model|data|skill")
682
+ .argument("<price>", "Price per unit")
683
+ .option("--name <n>", "Display name")
684
+ .option("--available <n>", "Available quantity", parseInt, 1)
685
+ .option("--json", "Output as JSON")
686
+ .action(async (seller, resourceType, price, options) => {
687
+ try {
688
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
689
+ const db = ctx.db.getDatabase();
690
+ const r = listResourceV2(db, {
691
+ sellerId: seller,
692
+ resourceType,
693
+ price: parseFloat(price),
694
+ name: options.name,
695
+ available: options.available,
696
+ });
697
+ if (options.json) console.log(JSON.stringify(r, null, 2));
698
+ else
699
+ logger.log(
700
+ `${chalk.green("✓")} listing ${chalk.cyan(r.id)} ${resourceType}@${price}`,
701
+ );
702
+ await shutdown();
703
+ } catch (err) {
704
+ logger.error(`Failed: ${err.message}`);
705
+ process.exit(1);
706
+ }
707
+ });
708
+
709
+ economy
710
+ .command("nft-mint-v2")
711
+ .description("Mint NFT with royalty tracking (Phase 85)")
712
+ .argument("<owner>", "Owner ID")
713
+ .argument("<asset-type>", "Asset type")
714
+ .option("--royalty <pct>", "Royalty percent (0-50)", parseFloat, 0)
715
+ .option("--metadata <json>", "Metadata JSON")
716
+ .option("--json", "Output as JSON")
717
+ .action(async (owner, assetType, options) => {
718
+ try {
719
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
720
+ const db = ctx.db.getDatabase();
721
+ const n = mintNFTV2(db, {
722
+ owner,
723
+ assetType,
724
+ royaltyPercent: options.royalty,
725
+ metadata: options.metadata ? JSON.parse(options.metadata) : {},
726
+ });
727
+ if (options.json) console.log(JSON.stringify(n, null, 2));
728
+ else
729
+ logger.log(
730
+ `${chalk.green("✓ Minted")} ${chalk.cyan(n.id)} ${assetType} royalty=${n.royaltyPercent}%`,
731
+ );
732
+ await shutdown();
733
+ } catch (err) {
734
+ logger.error(`Failed: ${err.message}`);
735
+ process.exit(1);
736
+ }
737
+ });
738
+
739
+ economy
740
+ .command("nft-list")
741
+ .description("List NFT for sale at a price (Phase 85)")
742
+ .argument("<id>", "NFT ID")
743
+ .argument("<price>", "Listing price")
744
+ .option("--json", "Output as JSON")
745
+ .action(async (id, price, options) => {
746
+ try {
747
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
748
+ const db = ctx.db.getDatabase();
749
+ const r = listNFT(db, id, parseFloat(price));
750
+ if (options.json) console.log(JSON.stringify(r, null, 2));
751
+ else
752
+ logger.log(`${chalk.green("✓ Listed")} ${chalk.cyan(id)}@${price}`);
753
+ await shutdown();
754
+ } catch (err) {
755
+ logger.error(`Failed: ${err.message}`);
756
+ process.exit(1);
757
+ }
758
+ });
759
+
760
+ economy
761
+ .command("nft-buy")
762
+ .description("Buy a listed NFT (Phase 85)")
763
+ .argument("<id>", "NFT ID")
764
+ .argument("<buyer>", "Buyer ID")
765
+ .option("--json", "Output as JSON")
766
+ .action(async (id, buyer, options) => {
767
+ try {
768
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
769
+ const db = ctx.db.getDatabase();
770
+ const r = buyNFT(db, id, buyer);
771
+ if (options.json) console.log(JSON.stringify(r, null, 2));
772
+ else
773
+ logger.log(
774
+ `${chalk.green("✓ Sold")} ${chalk.cyan(id)} → ${buyer} for ${r.price} (royalty ${r.royalty})`,
775
+ );
776
+ await shutdown();
777
+ } catch (err) {
778
+ logger.error(`Failed: ${err.message}`);
779
+ process.exit(1);
780
+ }
781
+ });
782
+
783
+ economy
784
+ .command("nft-burn")
785
+ .description("Burn an NFT (Phase 85)")
786
+ .argument("<id>", "NFT ID")
787
+ .option("--json", "Output as JSON")
788
+ .action(async (id, options) => {
789
+ try {
790
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
791
+ const db = ctx.db.getDatabase();
792
+ const r = burnNFT(db, id);
793
+ if (options.json) console.log(JSON.stringify(r, null, 2));
794
+ else logger.log(`${chalk.red("🔥 Burned")} ${chalk.cyan(id)}`);
795
+ await shutdown();
796
+ } catch (err) {
797
+ logger.error(`Failed: ${err.message}`);
798
+ process.exit(1);
799
+ }
800
+ });
801
+
802
+ economy
803
+ .command("nft-status")
804
+ .description("Get NFT status (Phase 85)")
805
+ .argument("<id>", "NFT ID")
806
+ .option("--json", "Output as JSON")
807
+ .action(async (id, options) => {
808
+ try {
809
+ await bootstrap({ verbose: program.opts().verbose });
810
+ const s = getNFTStatus(id);
811
+ if (options.json) console.log(JSON.stringify(s, null, 2));
812
+ else if (!s) logger.info("No NFT found.");
813
+ else
814
+ logger.log(
815
+ `${chalk.cyan(id)} ${chalk.yellow(s.status)} royalty=${s.royaltyPercent}%`,
816
+ );
817
+ await shutdown();
818
+ } catch (err) {
819
+ logger.error(`Failed: ${err.message}`);
820
+ process.exit(1);
821
+ }
822
+ });
823
+
824
+ economy
825
+ .command("contribute-task")
826
+ .description("Record a weighted task contribution (Phase 85)")
827
+ .argument("<task-id>", "Task ID")
828
+ .argument("<agent-id>", "Agent ID")
829
+ .option("--weight <w>", "Weight", parseFloat, 1)
830
+ .option("--json", "Output as JSON")
831
+ .action(async (taskId, agentId, options) => {
832
+ try {
833
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
834
+ const db = ctx.db.getDatabase();
835
+ const r = recordTaskContribution(db, {
836
+ taskId,
837
+ agentId,
838
+ weight: options.weight,
839
+ });
840
+ if (options.json) console.log(JSON.stringify(r, null, 2));
841
+ else
842
+ logger.log(
843
+ `${chalk.green("✓")} ${chalk.cyan(agentId)} → ${taskId} weight=${options.weight}`,
844
+ );
845
+ await shutdown();
846
+ } catch (err) {
847
+ logger.error(`Failed: ${err.message}`);
848
+ process.exit(1);
849
+ }
850
+ });
851
+
852
+ economy
853
+ .command("contributions-task")
854
+ .description("List contributions for a task (Phase 85)")
855
+ .argument("<task-id>", "Task ID")
856
+ .option("--json", "Output as JSON")
857
+ .action(async (taskId, options) => {
858
+ try {
859
+ await bootstrap({ verbose: program.opts().verbose });
860
+ const r = getTaskContributions(taskId);
861
+ if (options.json) console.log(JSON.stringify(r, null, 2));
862
+ else if (r.length === 0) logger.info("No contributions.");
863
+ else
864
+ r.forEach((c) =>
865
+ logger.log(` ${chalk.cyan(c.agentId)} weight=${c.weight}`),
866
+ );
867
+ await shutdown();
868
+ } catch (err) {
869
+ logger.error(`Failed: ${err.message}`);
870
+ process.exit(1);
871
+ }
872
+ });
873
+
874
+ economy
875
+ .command("distribute-v2")
876
+ .description("Distribute revenue across task contributors (Phase 85)")
877
+ .argument("<task-id>", "Task ID")
878
+ .argument("<total>", "Total amount to distribute")
879
+ .option("--json", "Output as JSON")
880
+ .action(async (taskId, total, options) => {
881
+ try {
882
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
883
+ const db = ctx.db.getDatabase();
884
+ const r = distributeRevenueV2(db, { taskId, total: parseFloat(total) });
885
+ if (options.json) console.log(JSON.stringify(r, null, 2));
886
+ else {
887
+ logger.log(chalk.bold(`Distributed ${total} for task ${taskId}:`));
888
+ r.shares.forEach((s) =>
889
+ logger.log(
890
+ ` ${chalk.cyan(s.agentId)} share=${chalk.yellow(s.share.toFixed(2))} balance=${s.newBalance.toFixed(2)}`,
891
+ ),
892
+ );
893
+ }
894
+ await shutdown();
895
+ } catch (err) {
896
+ logger.error(`Failed: ${err.message}`);
897
+ process.exit(1);
898
+ }
899
+ });
900
+
901
+ economy
902
+ .command("distributions")
903
+ .description("List distribution records (Phase 85)")
904
+ .option("-t, --task <id>", "Filter by task ID")
905
+ .option("--json", "Output as JSON")
906
+ .action(async (options) => {
907
+ try {
908
+ await bootstrap({ verbose: program.opts().verbose });
909
+ const r = listDistributions({ taskId: options.task });
910
+ if (options.json) console.log(JSON.stringify(r, null, 2));
911
+ else if (r.length === 0) logger.info("No distributions.");
912
+ else
913
+ r.forEach((d) =>
914
+ logger.log(
915
+ ` ${chalk.cyan(d.id.slice(0, 8))} task=${d.taskId} total=${chalk.yellow(d.total)} shares=${d.shares.length}`,
916
+ ),
917
+ );
918
+ await shutdown();
919
+ } catch (err) {
920
+ logger.error(`Failed: ${err.message}`);
921
+ process.exit(1);
922
+ }
923
+ });
924
+
925
+ economy
926
+ .command("stats-v2")
927
+ .description("Extended economy stats (Phase 85)")
928
+ .option("--json", "Output as JSON")
929
+ .action(async (options) => {
930
+ try {
931
+ await bootstrap({ verbose: program.opts().verbose });
932
+ const s = getEconomyStatsV2();
933
+ if (options.json) console.log(JSON.stringify(s, null, 2));
934
+ else {
935
+ logger.log(chalk.bold("Economy stats (Phase 85):"));
936
+ logger.log(` accounts: ${chalk.cyan(s.totalAccounts)}`);
937
+ logger.log(` channels: ${chalk.cyan(s.totalChannels)}`);
938
+ for (const [k, v] of Object.entries(s.channelsByStatus))
939
+ logger.log(` ${k}: ${v}`);
940
+ logger.log(` listings: ${chalk.cyan(s.totalListings)}`);
941
+ logger.log(` NFTs: ${chalk.cyan(s.totalNFTs)}`);
942
+ for (const [k, v] of Object.entries(s.nftByStatus))
943
+ logger.log(` ${k}: ${v}`);
944
+ logger.log(` price models: ${chalk.cyan(s.priceModels)}`);
945
+ logger.log(` distributions: ${chalk.cyan(s.distributions)}`);
946
+ }
947
+ await shutdown();
948
+ } catch (err) {
949
+ logger.error(`Failed: ${err.message}`);
950
+ process.exit(1);
951
+ }
952
+ });
375
953
  }