chainlesschain 0.51.0 → 0.66.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 (39) 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/agent-network.js +785 -0
  9. package/src/commands/automation.js +654 -0
  10. package/src/commands/dao.js +565 -0
  11. package/src/commands/did-v2.js +620 -0
  12. package/src/commands/economy.js +578 -0
  13. package/src/commands/evolution.js +391 -0
  14. package/src/commands/hmemory.js +442 -0
  15. package/src/commands/perf.js +433 -0
  16. package/src/commands/pipeline.js +449 -0
  17. package/src/commands/plugin-ecosystem.js +517 -0
  18. package/src/commands/sandbox.js +401 -0
  19. package/src/commands/social.js +311 -0
  20. package/src/commands/sso.js +798 -0
  21. package/src/commands/workflow.js +320 -0
  22. package/src/commands/zkp.js +227 -1
  23. package/src/index.js +21 -0
  24. package/src/lib/agent-economy.js +479 -0
  25. package/src/lib/agent-network.js +1121 -0
  26. package/src/lib/automation-engine.js +948 -0
  27. package/src/lib/dao-governance.js +569 -0
  28. package/src/lib/did-v2-manager.js +1127 -0
  29. package/src/lib/evolution-system.js +453 -0
  30. package/src/lib/hierarchical-memory.js +481 -0
  31. package/src/lib/perf-tuning.js +734 -0
  32. package/src/lib/pipeline-orchestrator.js +928 -0
  33. package/src/lib/plugin-ecosystem.js +1109 -0
  34. package/src/lib/sandbox-v2.js +306 -0
  35. package/src/lib/social-graph-analytics.js +707 -0
  36. package/src/lib/sso-manager.js +841 -0
  37. package/src/lib/workflow-engine.js +454 -1
  38. package/src/lib/zkp-engine.js +249 -20
  39. package/src/assets/web-panel/assets/Dashboard-BS-tzGNj.css +0 -1
@@ -18,6 +18,23 @@ import {
18
18
  getSandbox,
19
19
  setQuota,
20
20
  monitorBehavior,
21
+ // Phase 87 V2
22
+ SANDBOX_STATUS,
23
+ PERMISSION_TYPE,
24
+ RISK_LEVEL,
25
+ QUOTA_TYPE,
26
+ pauseSandboxV2,
27
+ resumeSandboxV2,
28
+ terminateSandboxV2,
29
+ setQuotaTyped,
30
+ enforcePermission,
31
+ checkQuotaV2,
32
+ getRiskLevel,
33
+ calculateRiskScore,
34
+ autoIsolate,
35
+ listIsolations,
36
+ filterAuditLog,
37
+ getSandboxStatsV2,
21
38
  } from "../lib/sandbox-v2.js";
22
39
 
23
40
  export function registerSandboxCommand(program) {
@@ -437,4 +454,388 @@ export function registerSandboxCommand(program) {
437
454
  process.exit(1);
438
455
  }
439
456
  });
457
+
458
+ // ═════════════════════════════════════════════════════════════════
459
+ // Phase 87 — Agent Security Sandbox 2.0 subcommands
460
+ // ═════════════════════════════════════════════════════════════════
461
+
462
+ // sandbox statuses
463
+ sandbox
464
+ .command("statuses")
465
+ .description("List sandbox lifecycle status enum values (Phase 87)")
466
+ .option("--json", "Output as JSON")
467
+ .action((options) => {
468
+ const values = Object.values(SANDBOX_STATUS);
469
+ if (options.json) console.log(JSON.stringify(values, null, 2));
470
+ else values.forEach((v) => logger.log(` ${chalk.cyan(v)}`));
471
+ });
472
+
473
+ // sandbox permission-types
474
+ sandbox
475
+ .command("permission-types")
476
+ .description("List permission type enum values (Phase 87)")
477
+ .option("--json", "Output as JSON")
478
+ .action((options) => {
479
+ const values = Object.values(PERMISSION_TYPE);
480
+ if (options.json) console.log(JSON.stringify(values, null, 2));
481
+ else values.forEach((v) => logger.log(` ${chalk.cyan(v)}`));
482
+ });
483
+
484
+ // sandbox risk-levels
485
+ sandbox
486
+ .command("risk-levels")
487
+ .description("List risk level enum values (Phase 87)")
488
+ .option("--json", "Output as JSON")
489
+ .action((options) => {
490
+ const values = Object.values(RISK_LEVEL);
491
+ if (options.json) console.log(JSON.stringify(values, null, 2));
492
+ else values.forEach((v) => logger.log(` ${chalk.cyan(v)}`));
493
+ });
494
+
495
+ // sandbox quota-types
496
+ sandbox
497
+ .command("quota-types")
498
+ .description("List quota type enum values (Phase 87)")
499
+ .option("--json", "Output as JSON")
500
+ .action((options) => {
501
+ const values = Object.values(QUOTA_TYPE);
502
+ if (options.json) console.log(JSON.stringify(values, null, 2));
503
+ else values.forEach((v) => logger.log(` ${chalk.cyan(v)}`));
504
+ });
505
+
506
+ // sandbox pause <id>
507
+ sandbox
508
+ .command("pause")
509
+ .description("Pause a running sandbox (Phase 87)")
510
+ .argument("<id>", "Sandbox ID")
511
+ .option("--json", "Output as JSON")
512
+ .action(async (id, options) => {
513
+ try {
514
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
515
+ const db = ctx.db.getDatabase();
516
+ const r = pauseSandboxV2(db, id);
517
+ if (options.json) console.log(JSON.stringify(r, null, 2));
518
+ else
519
+ logger.log(
520
+ `${chalk.green("✓ Paused")} ${chalk.cyan(id)} (was ${chalk.yellow(r.previousStatus)})`,
521
+ );
522
+ await shutdown();
523
+ } catch (err) {
524
+ logger.error(`Failed: ${err.message}`);
525
+ process.exit(1);
526
+ }
527
+ });
528
+
529
+ // sandbox resume <id>
530
+ sandbox
531
+ .command("resume")
532
+ .description("Resume a paused sandbox (Phase 87)")
533
+ .argument("<id>", "Sandbox ID")
534
+ .option("--json", "Output as JSON")
535
+ .action(async (id, options) => {
536
+ try {
537
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
538
+ const db = ctx.db.getDatabase();
539
+ const r = resumeSandboxV2(db, id);
540
+ if (options.json) console.log(JSON.stringify(r, null, 2));
541
+ else logger.log(`${chalk.green("✓ Resumed")} ${chalk.cyan(id)}`);
542
+ await shutdown();
543
+ } catch (err) {
544
+ logger.error(`Failed: ${err.message}`);
545
+ process.exit(1);
546
+ }
547
+ });
548
+
549
+ // sandbox terminate <id>
550
+ sandbox
551
+ .command("terminate")
552
+ .description(
553
+ "Terminate a sandbox (Phase 87 canonical; more explicit than destroy)",
554
+ )
555
+ .argument("<id>", "Sandbox ID")
556
+ .option("--reason <reason>", "Termination reason", "manual")
557
+ .option("--json", "Output as JSON")
558
+ .action(async (id, options) => {
559
+ try {
560
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
561
+ const db = ctx.db.getDatabase();
562
+ const r = terminateSandboxV2(db, id, options.reason);
563
+ if (options.json) console.log(JSON.stringify(r, null, 2));
564
+ else
565
+ logger.log(
566
+ `${chalk.green("✓ Terminated")} ${chalk.cyan(id)} reason=${chalk.yellow(r.reason)}`,
567
+ );
568
+ await shutdown();
569
+ } catch (err) {
570
+ logger.error(`Failed: ${err.message}`);
571
+ process.exit(1);
572
+ }
573
+ });
574
+
575
+ // sandbox set-quota-typed <id> <type> <limit>
576
+ sandbox
577
+ .command("set-quota-typed")
578
+ .description("Set a single quota by type (Phase 87)")
579
+ .argument("<id>", "Sandbox ID")
580
+ .argument(
581
+ "<type>",
582
+ "Quota type (cpu_percent|memory_mb|disk_mb|network_kbps|process_count)",
583
+ )
584
+ .argument("<limit>", "Numeric limit")
585
+ .option("--json", "Output as JSON")
586
+ .action(async (id, type, limit, options) => {
587
+ try {
588
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
589
+ const db = ctx.db.getDatabase();
590
+ const r = setQuotaTyped(db, id, type, Number(limit));
591
+ if (options.json) console.log(JSON.stringify(r, null, 2));
592
+ else
593
+ logger.log(
594
+ `${chalk.green("✓ Quota set")} ${chalk.cyan(id)} ${type}=${chalk.yellow(limit)}`,
595
+ );
596
+ await shutdown();
597
+ } catch (err) {
598
+ logger.error(`Failed: ${err.message}`);
599
+ process.exit(1);
600
+ }
601
+ });
602
+
603
+ // sandbox check-permission <id> <type> <target>
604
+ sandbox
605
+ .command("check-permission")
606
+ .description(
607
+ "Check whether a sandbox may perform a permission op (Phase 87)",
608
+ )
609
+ .argument("<id>", "Sandbox ID")
610
+ .argument(
611
+ "<type>",
612
+ "Permission type (filesystem|network|syscall|ipc|process)",
613
+ )
614
+ .argument("<target>", "Target (path / host / syscall name)")
615
+ .option("--mode <mode>", "File mode (read|write)", "read")
616
+ .option("--json", "Output as JSON")
617
+ .action(async (id, type, target, options) => {
618
+ try {
619
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
620
+ const db = ctx.db.getDatabase();
621
+ const sandbox = getSandbox(db, id);
622
+ if (!sandbox) {
623
+ logger.error(`Sandbox not found: ${id}`);
624
+ await shutdown();
625
+ process.exit(1);
626
+ return;
627
+ }
628
+ const r = enforcePermission(sandbox, {
629
+ type,
630
+ target,
631
+ mode: options.mode,
632
+ });
633
+ if (options.json) console.log(JSON.stringify(r, null, 2));
634
+ else
635
+ logger.log(
636
+ `${r.allowed ? chalk.green("allowed") : chalk.red("denied")} ${type} ${options.mode} ${target}`,
637
+ );
638
+ await shutdown();
639
+ } catch (err) {
640
+ logger.error(`Failed: ${err.message}`);
641
+ process.exit(1);
642
+ }
643
+ });
644
+
645
+ // sandbox check-quota <id> <type> [amount]
646
+ sandbox
647
+ .command("check-quota")
648
+ .description("Check quota availability for a type (Phase 87)")
649
+ .argument("<id>", "Sandbox ID")
650
+ .argument("<type>", "Quota type")
651
+ .argument("[amount]", "Amount to check", "0")
652
+ .option("--json", "Output as JSON")
653
+ .action(async (id, type, amount, options) => {
654
+ try {
655
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
656
+ const db = ctx.db.getDatabase();
657
+ const sandbox = getSandbox(db, id);
658
+ if (!sandbox) {
659
+ logger.error(`Sandbox not found: ${id}`);
660
+ await shutdown();
661
+ process.exit(1);
662
+ return;
663
+ }
664
+ const r = checkQuotaV2(sandbox, type, Number(amount));
665
+ if (options.json) console.log(JSON.stringify(r, null, 2));
666
+ else
667
+ logger.log(
668
+ `${r.ok ? chalk.green("ok") : chalk.red("exceeded")} ${type}: ${r.current}/${r.limit ?? "∞"} (remaining ${r.remaining})`,
669
+ );
670
+ await shutdown();
671
+ } catch (err) {
672
+ logger.error(`Failed: ${err.message}`);
673
+ process.exit(1);
674
+ }
675
+ });
676
+
677
+ // sandbox risk-score <id>
678
+ sandbox
679
+ .command("risk-score")
680
+ .description("Compute risk score + risk level for a sandbox (Phase 87)")
681
+ .argument("<id>", "Sandbox ID")
682
+ .option("--json", "Output as JSON")
683
+ .action(async (id, options) => {
684
+ try {
685
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
686
+ const db = ctx.db.getDatabase();
687
+ const r = calculateRiskScore(db, id);
688
+ if (options.json) console.log(JSON.stringify(r, null, 2));
689
+ else {
690
+ const color =
691
+ r.riskLevel === RISK_LEVEL.CRITICAL
692
+ ? chalk.red
693
+ : r.riskLevel === RISK_LEVEL.HIGH
694
+ ? chalk.magenta
695
+ : r.riskLevel === RISK_LEVEL.MEDIUM
696
+ ? chalk.yellow
697
+ : chalk.green;
698
+ logger.log(
699
+ `risk=${color(r.riskLevel)} score=${chalk.cyan(r.riskScore)} patterns=${r.patterns.length} events=${r.totalEvents}`,
700
+ );
701
+ }
702
+ await shutdown();
703
+ } catch (err) {
704
+ logger.error(`Failed: ${err.message}`);
705
+ process.exit(1);
706
+ }
707
+ });
708
+
709
+ // sandbox risk-level <score>
710
+ sandbox
711
+ .command("risk-level")
712
+ .description("Map a risk score to a RISK_LEVEL bucket (Phase 87)")
713
+ .argument("<score>", "Numeric score 0-100")
714
+ .option("--json", "Output as JSON")
715
+ .action((score, options) => {
716
+ const level = getRiskLevel(Number(score));
717
+ if (options.json)
718
+ console.log(JSON.stringify({ score: Number(score), level }, null, 2));
719
+ else logger.log(`score=${score} → ${chalk.cyan(level)}`);
720
+ });
721
+
722
+ // sandbox auto-isolate <id>
723
+ sandbox
724
+ .command("auto-isolate")
725
+ .description("Auto-isolate a sandbox: record + terminate (Phase 87)")
726
+ .argument("<id>", "Sandbox ID")
727
+ .option("--reason <reason>", "Isolation reason", "high-risk")
728
+ .option("--json", "Output as JSON")
729
+ .action(async (id, options) => {
730
+ try {
731
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
732
+ const db = ctx.db.getDatabase();
733
+ const entry = autoIsolate(db, id, options.reason);
734
+ if (options.json) console.log(JSON.stringify(entry, null, 2));
735
+ else
736
+ logger.log(
737
+ `${chalk.red("⊘ Isolated")} ${chalk.cyan(id)} reason=${chalk.yellow(entry.reason)} at ${entry.isolatedAt}`,
738
+ );
739
+ await shutdown();
740
+ } catch (err) {
741
+ logger.error(`Failed: ${err.message}`);
742
+ process.exit(1);
743
+ }
744
+ });
745
+
746
+ // sandbox isolations
747
+ sandbox
748
+ .command("isolations")
749
+ .description("List isolation records (Phase 87)")
750
+ .option("-s, --sandbox <id>", "Filter by sandbox ID")
751
+ .option("--reason <reason>", "Filter by reason")
752
+ .option("--json", "Output as JSON")
753
+ .action(async (options) => {
754
+ try {
755
+ await bootstrap({ verbose: program.opts().verbose });
756
+ const items = listIsolations({
757
+ sandboxId: options.sandbox,
758
+ reason: options.reason,
759
+ });
760
+ if (options.json) console.log(JSON.stringify(items, null, 2));
761
+ else if (items.length === 0) logger.info("No isolation records.");
762
+ else
763
+ items.forEach((i) =>
764
+ logger.log(
765
+ ` ${chalk.cyan(i.sandboxId)} reason=${chalk.yellow(i.reason)} at=${i.isolatedAt}`,
766
+ ),
767
+ );
768
+ await shutdown();
769
+ } catch (err) {
770
+ logger.error(`Failed: ${err.message}`);
771
+ process.exit(1);
772
+ }
773
+ });
774
+
775
+ // sandbox audit-filter <id>
776
+ sandbox
777
+ .command("audit-filter")
778
+ .description("Filter audit log by event types / time range (Phase 87)")
779
+ .argument("[id]", "Sandbox ID (omit for all)")
780
+ .option("-e, --events <types>", "Comma-separated event types")
781
+ .option("--from <iso>", "ISO timestamp lower bound")
782
+ .option("--to <iso>", "ISO timestamp upper bound")
783
+ .option("-l, --limit <n>", "Max entries to return", parseInt)
784
+ .option("--json", "Output as JSON")
785
+ .action(async (id, options) => {
786
+ try {
787
+ const ctx = await bootstrap({ verbose: program.opts().verbose });
788
+ const db = ctx.db.getDatabase();
789
+ const filter = {};
790
+ if (options.events)
791
+ filter.eventTypes = options.events.split(",").map((s) => s.trim());
792
+ if (options.from || options.to)
793
+ filter.timeRange = { from: options.from, to: options.to };
794
+ if (options.limit) filter.limit = options.limit;
795
+ const entries = filterAuditLog(db, id, filter);
796
+ if (options.json) console.log(JSON.stringify(entries, null, 2));
797
+ else if (entries.length === 0)
798
+ logger.info("No matching audit entries.");
799
+ else
800
+ entries.forEach((e) =>
801
+ logger.log(
802
+ ` ${chalk.gray(e.timestamp)} ${chalk.cyan(e.sandboxId)} ${chalk.yellow(e.action)}`,
803
+ ),
804
+ );
805
+ await shutdown();
806
+ } catch (err) {
807
+ logger.error(`Failed: ${err.message}`);
808
+ process.exit(1);
809
+ }
810
+ });
811
+
812
+ // sandbox stats-v2
813
+ sandbox
814
+ .command("stats-v2")
815
+ .description(
816
+ "Extended V2 stats (byStatus / auditByAction / isolations) (Phase 87)",
817
+ )
818
+ .option("--json", "Output as JSON")
819
+ .action(async (options) => {
820
+ try {
821
+ await bootstrap({ verbose: program.opts().verbose });
822
+ const stats = getSandboxStatsV2();
823
+ if (options.json) console.log(JSON.stringify(stats, null, 2));
824
+ else {
825
+ logger.log(chalk.bold("Sandbox stats (Phase 87):"));
826
+ logger.log(` total: ${chalk.cyan(stats.totalSandboxes)}`);
827
+ logger.log(` by status:`);
828
+ for (const [k, v] of Object.entries(stats.byStatus))
829
+ logger.log(` ${k}: ${chalk.cyan(v)}`);
830
+ logger.log(` audit events: ${chalk.cyan(stats.auditEventCount)}`);
831
+ logger.log(
832
+ ` isolations: total=${chalk.cyan(stats.isolations.total)}`,
833
+ );
834
+ }
835
+ await shutdown();
836
+ } catch (err) {
837
+ logger.error(`Failed: ${err.message}`);
838
+ process.exit(1);
839
+ }
840
+ });
440
841
  }