chainlesschain 0.132.0 → 0.145.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 (135) hide show
  1. package/package.json +1 -1
  2. package/src/commands/a2a.js +230 -0
  3. package/src/commands/activitypub.js +191 -0
  4. package/src/commands/agent.js +601 -0
  5. package/src/commands/audit.js +206 -0
  6. package/src/commands/bi.js +186 -0
  7. package/src/commands/bm25.js +162 -0
  8. package/src/commands/browse.js +225 -0
  9. package/src/commands/ccron.js +178 -0
  10. package/src/commands/chat.js +207 -0
  11. package/src/commands/compliance.js +420 -0
  12. package/src/commands/compt.js +176 -0
  13. package/src/commands/consol.js +237 -0
  14. package/src/commands/cowork.js +588 -0
  15. package/src/commands/crosschain.js +216 -0
  16. package/src/commands/dao.js +216 -0
  17. package/src/commands/dlp.js +206 -0
  18. package/src/commands/economy.js +211 -0
  19. package/src/commands/evolution.js +209 -0
  20. package/src/commands/evomap.js +216 -0
  21. package/src/commands/fflag.js +230 -0
  22. package/src/commands/git.js +185 -0
  23. package/src/commands/hardening.js +209 -0
  24. package/src/commands/hmemory.js +210 -0
  25. package/src/commands/incentive.js +209 -0
  26. package/src/commands/inference.js +178 -0
  27. package/src/commands/itbudget.js +161 -0
  28. package/src/commands/kg.js +206 -0
  29. package/src/commands/lowcode.js +201 -0
  30. package/src/commands/marketplace.js +206 -0
  31. package/src/commands/matrix.js +214 -0
  32. package/src/commands/mcpscaf.js +153 -0
  33. package/src/commands/meminj.js +153 -0
  34. package/src/commands/nostr.js +213 -0
  35. package/src/commands/orchestrate.js +217 -0
  36. package/src/commands/orchgov.js +156 -0
  37. package/src/commands/pdfp.js +160 -0
  38. package/src/commands/perf.js +176 -0
  39. package/src/commands/perm.js +156 -0
  40. package/src/commands/pipeline.js +211 -0
  41. package/src/commands/planmode.js +154 -0
  42. package/src/commands/privacy.js +203 -0
  43. package/src/commands/promcomp.js +166 -0
  44. package/src/commands/recommend.js +185 -0
  45. package/src/commands/reputation.js +208 -0
  46. package/src/commands/sandbox.js +206 -0
  47. package/src/commands/seshhook.js +153 -0
  48. package/src/commands/seshsearch.js +149 -0
  49. package/src/commands/seshtail.js +152 -0
  50. package/src/commands/seshu.js +160 -0
  51. package/src/commands/sganal.js +172 -0
  52. package/src/commands/siem.js +207 -0
  53. package/src/commands/sla.js +212 -0
  54. package/src/commands/slotfill.js +154 -0
  55. package/src/commands/social.js +159 -0
  56. package/src/commands/stress.js +206 -0
  57. package/src/commands/svccont.js +157 -0
  58. package/src/commands/terraform.js +206 -0
  59. package/src/commands/tms.js +183 -0
  60. package/src/commands/topiccls.js +158 -0
  61. package/src/commands/uprof.js +154 -0
  62. package/src/commands/vcheck.js +172 -0
  63. package/src/commands/webfetch.js +150 -0
  64. package/src/commands/zkp.js +218 -0
  65. package/src/harness/prompt-compressor.js +331 -0
  66. package/src/index.js +101 -1
  67. package/src/lib/a2a-protocol.js +373 -0
  68. package/src/lib/activitypub-bridge.js +343 -0
  69. package/src/lib/agent-economy.js +358 -0
  70. package/src/lib/app-builder.js +338 -0
  71. package/src/lib/audit-logger.js +321 -0
  72. package/src/lib/autonomous-agent.js +341 -0
  73. package/src/lib/bi-engine.js +339 -0
  74. package/src/lib/bm25-search.js +333 -0
  75. package/src/lib/browser-automation.js +352 -0
  76. package/src/lib/chat-core.js +336 -0
  77. package/src/lib/claude-code-bridge.js +341 -0
  78. package/src/lib/compliance-framework-reporter.js +359 -0
  79. package/src/lib/compliance-manager.js +330 -0
  80. package/src/lib/compression-telemetry.js +333 -0
  81. package/src/lib/content-recommender.js +370 -0
  82. package/src/lib/cowork-cron.js +330 -0
  83. package/src/lib/cowork-learning.js +333 -0
  84. package/src/lib/cowork-task-runner.js +362 -0
  85. package/src/lib/cowork-workflow.js +327 -0
  86. package/src/lib/cross-chain.js +365 -0
  87. package/src/lib/dao-governance.js +339 -0
  88. package/src/lib/dlp-engine.js +343 -0
  89. package/src/lib/evolution-system.js +336 -0
  90. package/src/lib/evomap-manager.js +339 -0
  91. package/src/lib/execution-backend.js +351 -0
  92. package/src/lib/feature-flags.js +330 -0
  93. package/src/lib/git-integration.js +343 -0
  94. package/src/lib/hardening-manager.js +341 -0
  95. package/src/lib/hierarchical-memory.js +341 -0
  96. package/src/lib/inference-network.js +362 -0
  97. package/src/lib/iteration-budget.js +357 -0
  98. package/src/lib/knowledge-graph.js +333 -0
  99. package/src/lib/matrix-bridge.js +339 -0
  100. package/src/lib/mcp-scaffold.js +345 -0
  101. package/src/lib/memory-injection.js +320 -0
  102. package/src/lib/nostr-bridge.js +342 -0
  103. package/src/lib/orchestrator.js +350 -0
  104. package/src/lib/pdf-parser.js +330 -0
  105. package/src/lib/perf-tuning.js +364 -0
  106. package/src/lib/permission-engine.js +319 -0
  107. package/src/lib/pipeline-orchestrator.js +345 -0
  108. package/src/lib/plan-mode.js +328 -0
  109. package/src/lib/privacy-computing.js +335 -0
  110. package/src/lib/prompt-compressor.js +1 -10
  111. package/src/lib/reputation-optimizer.js +340 -0
  112. package/src/lib/sandbox-v2.js +327 -0
  113. package/src/lib/service-container.js +342 -0
  114. package/src/lib/session-consolidator.js +352 -0
  115. package/src/lib/session-hooks.js +340 -0
  116. package/src/lib/session-search.js +334 -0
  117. package/src/lib/session-tail.js +320 -0
  118. package/src/lib/session-usage.js +329 -0
  119. package/src/lib/siem-exporter.js +352 -0
  120. package/src/lib/skill-marketplace.js +345 -0
  121. package/src/lib/sla-manager.js +341 -0
  122. package/src/lib/slot-filler.js +333 -0
  123. package/src/lib/social-graph-analytics.js +327 -0
  124. package/src/lib/social-graph.js +304 -0
  125. package/src/lib/stress-tester.js +342 -0
  126. package/src/lib/sub-agent-registry.js +359 -0
  127. package/src/lib/task-model-selector.js +333 -0
  128. package/src/lib/terraform-manager.js +333 -0
  129. package/src/lib/todo-manager.js +339 -0
  130. package/src/lib/token-incentive.js +341 -0
  131. package/src/lib/topic-classifier.js +353 -0
  132. package/src/lib/user-profile.js +325 -0
  133. package/src/lib/version-checker.js +335 -0
  134. package/src/lib/web-fetch.js +322 -0
  135. package/src/lib/zkp-engine.js +342 -0
@@ -492,3 +492,344 @@ Reply with a JSON object: { "action": "retry|add_step|skip", "newParams": {...},
492
492
  return null;
493
493
  }
494
494
  }
495
+
496
+ // ===== V2 Surface: Autonomous Agent governance overlay (CLI v0.138.0) =====
497
+ export const AUTOAGENT_MATURITY_V2 = Object.freeze({
498
+ PENDING: "pending",
499
+ ACTIVE: "active",
500
+ PAUSED: "paused",
501
+ ARCHIVED: "archived",
502
+ });
503
+ export const AUTOAGENT_RUN_LIFECYCLE_V2 = Object.freeze({
504
+ QUEUED: "queued",
505
+ RUNNING: "running",
506
+ COMPLETED: "completed",
507
+ FAILED: "failed",
508
+ CANCELLED: "cancelled",
509
+ });
510
+
511
+ const _aaTrans = new Map([
512
+ [
513
+ AUTOAGENT_MATURITY_V2.PENDING,
514
+ new Set([AUTOAGENT_MATURITY_V2.ACTIVE, AUTOAGENT_MATURITY_V2.ARCHIVED]),
515
+ ],
516
+ [
517
+ AUTOAGENT_MATURITY_V2.ACTIVE,
518
+ new Set([AUTOAGENT_MATURITY_V2.PAUSED, AUTOAGENT_MATURITY_V2.ARCHIVED]),
519
+ ],
520
+ [
521
+ AUTOAGENT_MATURITY_V2.PAUSED,
522
+ new Set([AUTOAGENT_MATURITY_V2.ACTIVE, AUTOAGENT_MATURITY_V2.ARCHIVED]),
523
+ ],
524
+ [AUTOAGENT_MATURITY_V2.ARCHIVED, new Set()],
525
+ ]);
526
+ const _aaTerminal = new Set([AUTOAGENT_MATURITY_V2.ARCHIVED]);
527
+ const _aaRunTrans = new Map([
528
+ [
529
+ AUTOAGENT_RUN_LIFECYCLE_V2.QUEUED,
530
+ new Set([
531
+ AUTOAGENT_RUN_LIFECYCLE_V2.RUNNING,
532
+ AUTOAGENT_RUN_LIFECYCLE_V2.CANCELLED,
533
+ ]),
534
+ ],
535
+ [
536
+ AUTOAGENT_RUN_LIFECYCLE_V2.RUNNING,
537
+ new Set([
538
+ AUTOAGENT_RUN_LIFECYCLE_V2.COMPLETED,
539
+ AUTOAGENT_RUN_LIFECYCLE_V2.FAILED,
540
+ AUTOAGENT_RUN_LIFECYCLE_V2.CANCELLED,
541
+ ]),
542
+ ],
543
+ [AUTOAGENT_RUN_LIFECYCLE_V2.COMPLETED, new Set()],
544
+ [AUTOAGENT_RUN_LIFECYCLE_V2.FAILED, new Set()],
545
+ [AUTOAGENT_RUN_LIFECYCLE_V2.CANCELLED, new Set()],
546
+ ]);
547
+
548
+ const _aaAgents = new Map();
549
+ const _aaRuns = new Map();
550
+ let _aaMaxActivePerOwner = 5;
551
+ let _aaMaxPendingRunsPerAgent = 10;
552
+ let _aaAgentIdleMs = 7 * 24 * 60 * 60 * 1000;
553
+ let _aaRunStuckMs = 30 * 60 * 1000;
554
+
555
+ function _aaPos(n, lbl) {
556
+ const v = Math.floor(Number(n));
557
+ if (!Number.isFinite(v) || v <= 0)
558
+ throw new Error(`${lbl} must be positive integer`);
559
+ return v;
560
+ }
561
+
562
+ export function setMaxActiveAutoAgentsPerOwnerV2(n) {
563
+ _aaMaxActivePerOwner = _aaPos(n, "maxActiveAutoAgentsPerOwner");
564
+ }
565
+ export function getMaxActiveAutoAgentsPerOwnerV2() {
566
+ return _aaMaxActivePerOwner;
567
+ }
568
+ export function setMaxPendingAutoAgentRunsPerAgentV2(n) {
569
+ _aaMaxPendingRunsPerAgent = _aaPos(n, "maxPendingAutoAgentRunsPerAgent");
570
+ }
571
+ export function getMaxPendingAutoAgentRunsPerAgentV2() {
572
+ return _aaMaxPendingRunsPerAgent;
573
+ }
574
+ export function setAutoAgentIdleMsV2(n) {
575
+ _aaAgentIdleMs = _aaPos(n, "autoAgentIdleMs");
576
+ }
577
+ export function getAutoAgentIdleMsV2() {
578
+ return _aaAgentIdleMs;
579
+ }
580
+ export function setAutoAgentRunStuckMsV2(n) {
581
+ _aaRunStuckMs = _aaPos(n, "autoAgentRunStuckMs");
582
+ }
583
+ export function getAutoAgentRunStuckMsV2() {
584
+ return _aaRunStuckMs;
585
+ }
586
+
587
+ export function _resetStateAutonomousAgentV2() {
588
+ _aaAgents.clear();
589
+ _aaRuns.clear();
590
+ _aaMaxActivePerOwner = 5;
591
+ _aaMaxPendingRunsPerAgent = 10;
592
+ _aaAgentIdleMs = 7 * 24 * 60 * 60 * 1000;
593
+ _aaRunStuckMs = 30 * 60 * 1000;
594
+ }
595
+
596
+ export function registerAutoAgentV2({ id, owner, goal, metadata } = {}) {
597
+ if (!id || typeof id !== "string") throw new Error("id is required");
598
+ if (!owner || typeof owner !== "string") throw new Error("owner is required");
599
+ if (_aaAgents.has(id)) throw new Error(`auto-agent ${id} already registered`);
600
+ const now = Date.now();
601
+ const a = {
602
+ id,
603
+ owner,
604
+ goal: goal || "",
605
+ status: AUTOAGENT_MATURITY_V2.PENDING,
606
+ createdAt: now,
607
+ updatedAt: now,
608
+ activatedAt: null,
609
+ archivedAt: null,
610
+ lastTouchedAt: now,
611
+ metadata: { ...(metadata || {}) },
612
+ };
613
+ _aaAgents.set(id, a);
614
+ return { ...a, metadata: { ...a.metadata } };
615
+ }
616
+ function _aaCheckA(from, to) {
617
+ const a = _aaTrans.get(from);
618
+ if (!a || !a.has(to))
619
+ throw new Error(`invalid auto-agent transition ${from} → ${to}`);
620
+ }
621
+ function _aaCountActive(owner) {
622
+ let n = 0;
623
+ for (const a of _aaAgents.values())
624
+ if (a.owner === owner && a.status === AUTOAGENT_MATURITY_V2.ACTIVE) n++;
625
+ return n;
626
+ }
627
+
628
+ export function activateAutoAgentV2(id) {
629
+ const a = _aaAgents.get(id);
630
+ if (!a) throw new Error(`auto-agent ${id} not found`);
631
+ _aaCheckA(a.status, AUTOAGENT_MATURITY_V2.ACTIVE);
632
+ const recovery = a.status === AUTOAGENT_MATURITY_V2.PAUSED;
633
+ if (!recovery) {
634
+ const c = _aaCountActive(a.owner);
635
+ if (c >= _aaMaxActivePerOwner)
636
+ throw new Error(
637
+ `max active auto-agents per owner (${_aaMaxActivePerOwner}) reached for ${a.owner}`,
638
+ );
639
+ }
640
+ const now = Date.now();
641
+ a.status = AUTOAGENT_MATURITY_V2.ACTIVE;
642
+ a.updatedAt = now;
643
+ a.lastTouchedAt = now;
644
+ if (!a.activatedAt) a.activatedAt = now;
645
+ return { ...a, metadata: { ...a.metadata } };
646
+ }
647
+ export function pauseAutoAgentV2(id) {
648
+ const a = _aaAgents.get(id);
649
+ if (!a) throw new Error(`auto-agent ${id} not found`);
650
+ _aaCheckA(a.status, AUTOAGENT_MATURITY_V2.PAUSED);
651
+ a.status = AUTOAGENT_MATURITY_V2.PAUSED;
652
+ a.updatedAt = Date.now();
653
+ return { ...a, metadata: { ...a.metadata } };
654
+ }
655
+ export function archiveAutoAgentV2(id) {
656
+ const a = _aaAgents.get(id);
657
+ if (!a) throw new Error(`auto-agent ${id} not found`);
658
+ _aaCheckA(a.status, AUTOAGENT_MATURITY_V2.ARCHIVED);
659
+ const now = Date.now();
660
+ a.status = AUTOAGENT_MATURITY_V2.ARCHIVED;
661
+ a.updatedAt = now;
662
+ if (!a.archivedAt) a.archivedAt = now;
663
+ return { ...a, metadata: { ...a.metadata } };
664
+ }
665
+ export function touchAutoAgentV2(id) {
666
+ const a = _aaAgents.get(id);
667
+ if (!a) throw new Error(`auto-agent ${id} not found`);
668
+ if (_aaTerminal.has(a.status))
669
+ throw new Error(`cannot touch terminal auto-agent ${id}`);
670
+ const now = Date.now();
671
+ a.lastTouchedAt = now;
672
+ a.updatedAt = now;
673
+ return { ...a, metadata: { ...a.metadata } };
674
+ }
675
+ export function getAutoAgentV2(id) {
676
+ const a = _aaAgents.get(id);
677
+ if (!a) return null;
678
+ return { ...a, metadata: { ...a.metadata } };
679
+ }
680
+ export function listAutoAgentsV2() {
681
+ return [..._aaAgents.values()].map((a) => ({
682
+ ...a,
683
+ metadata: { ...a.metadata },
684
+ }));
685
+ }
686
+
687
+ function _aaCountPendingRuns(aid) {
688
+ let n = 0;
689
+ for (const r of _aaRuns.values())
690
+ if (
691
+ r.agentId === aid &&
692
+ (r.status === AUTOAGENT_RUN_LIFECYCLE_V2.QUEUED ||
693
+ r.status === AUTOAGENT_RUN_LIFECYCLE_V2.RUNNING)
694
+ )
695
+ n++;
696
+ return n;
697
+ }
698
+
699
+ export function createAutoAgentRunV2({ id, agentId, prompt, metadata } = {}) {
700
+ if (!id || typeof id !== "string") throw new Error("id is required");
701
+ if (!agentId || typeof agentId !== "string")
702
+ throw new Error("agentId is required");
703
+ if (_aaRuns.has(id)) throw new Error(`auto-agent run ${id} already exists`);
704
+ if (!_aaAgents.has(agentId))
705
+ throw new Error(`auto-agent ${agentId} not found`);
706
+ const pending = _aaCountPendingRuns(agentId);
707
+ if (pending >= _aaMaxPendingRunsPerAgent)
708
+ throw new Error(
709
+ `max pending auto-agent runs per agent (${_aaMaxPendingRunsPerAgent}) reached for ${agentId}`,
710
+ );
711
+ const now = Date.now();
712
+ const r = {
713
+ id,
714
+ agentId,
715
+ prompt: prompt || "",
716
+ status: AUTOAGENT_RUN_LIFECYCLE_V2.QUEUED,
717
+ createdAt: now,
718
+ updatedAt: now,
719
+ startedAt: null,
720
+ settledAt: null,
721
+ metadata: { ...(metadata || {}) },
722
+ };
723
+ _aaRuns.set(id, r);
724
+ return { ...r, metadata: { ...r.metadata } };
725
+ }
726
+ function _aaCheckR(from, to) {
727
+ const a = _aaRunTrans.get(from);
728
+ if (!a || !a.has(to))
729
+ throw new Error(`invalid auto-agent run transition ${from} → ${to}`);
730
+ }
731
+ export function startAutoAgentRunV2(id) {
732
+ const r = _aaRuns.get(id);
733
+ if (!r) throw new Error(`auto-agent run ${id} not found`);
734
+ _aaCheckR(r.status, AUTOAGENT_RUN_LIFECYCLE_V2.RUNNING);
735
+ const now = Date.now();
736
+ r.status = AUTOAGENT_RUN_LIFECYCLE_V2.RUNNING;
737
+ r.updatedAt = now;
738
+ if (!r.startedAt) r.startedAt = now;
739
+ return { ...r, metadata: { ...r.metadata } };
740
+ }
741
+ export function completeAutoAgentRunV2(id) {
742
+ const r = _aaRuns.get(id);
743
+ if (!r) throw new Error(`auto-agent run ${id} not found`);
744
+ _aaCheckR(r.status, AUTOAGENT_RUN_LIFECYCLE_V2.COMPLETED);
745
+ const now = Date.now();
746
+ r.status = AUTOAGENT_RUN_LIFECYCLE_V2.COMPLETED;
747
+ r.updatedAt = now;
748
+ if (!r.settledAt) r.settledAt = now;
749
+ return { ...r, metadata: { ...r.metadata } };
750
+ }
751
+ export function failAutoAgentRunV2(id, reason) {
752
+ const r = _aaRuns.get(id);
753
+ if (!r) throw new Error(`auto-agent run ${id} not found`);
754
+ _aaCheckR(r.status, AUTOAGENT_RUN_LIFECYCLE_V2.FAILED);
755
+ const now = Date.now();
756
+ r.status = AUTOAGENT_RUN_LIFECYCLE_V2.FAILED;
757
+ r.updatedAt = now;
758
+ if (!r.settledAt) r.settledAt = now;
759
+ if (reason) r.metadata.failReason = String(reason);
760
+ return { ...r, metadata: { ...r.metadata } };
761
+ }
762
+ export function cancelAutoAgentRunV2(id, reason) {
763
+ const r = _aaRuns.get(id);
764
+ if (!r) throw new Error(`auto-agent run ${id} not found`);
765
+ _aaCheckR(r.status, AUTOAGENT_RUN_LIFECYCLE_V2.CANCELLED);
766
+ const now = Date.now();
767
+ r.status = AUTOAGENT_RUN_LIFECYCLE_V2.CANCELLED;
768
+ r.updatedAt = now;
769
+ if (!r.settledAt) r.settledAt = now;
770
+ if (reason) r.metadata.cancelReason = String(reason);
771
+ return { ...r, metadata: { ...r.metadata } };
772
+ }
773
+ export function getAutoAgentRunV2(id) {
774
+ const r = _aaRuns.get(id);
775
+ if (!r) return null;
776
+ return { ...r, metadata: { ...r.metadata } };
777
+ }
778
+ export function listAutoAgentRunsV2() {
779
+ return [..._aaRuns.values()].map((r) => ({
780
+ ...r,
781
+ metadata: { ...r.metadata },
782
+ }));
783
+ }
784
+
785
+ export function autoPauseIdleAutoAgentsV2({ now } = {}) {
786
+ const t = now ?? Date.now();
787
+ const flipped = [];
788
+ for (const a of _aaAgents.values())
789
+ if (
790
+ a.status === AUTOAGENT_MATURITY_V2.ACTIVE &&
791
+ t - a.lastTouchedAt >= _aaAgentIdleMs
792
+ ) {
793
+ a.status = AUTOAGENT_MATURITY_V2.PAUSED;
794
+ a.updatedAt = t;
795
+ flipped.push(a.id);
796
+ }
797
+ return { flipped, count: flipped.length };
798
+ }
799
+ export function autoFailStuckAutoAgentRunsV2({ now } = {}) {
800
+ const t = now ?? Date.now();
801
+ const flipped = [];
802
+ for (const r of _aaRuns.values())
803
+ if (
804
+ r.status === AUTOAGENT_RUN_LIFECYCLE_V2.RUNNING &&
805
+ r.startedAt != null &&
806
+ t - r.startedAt >= _aaRunStuckMs
807
+ ) {
808
+ r.status = AUTOAGENT_RUN_LIFECYCLE_V2.FAILED;
809
+ r.updatedAt = t;
810
+ if (!r.settledAt) r.settledAt = t;
811
+ r.metadata.failReason = "auto-fail-stuck";
812
+ flipped.push(r.id);
813
+ }
814
+ return { flipped, count: flipped.length };
815
+ }
816
+
817
+ export function getAutonomousAgentGovStatsV2() {
818
+ const agentsByStatus = {};
819
+ for (const s of Object.values(AUTOAGENT_MATURITY_V2)) agentsByStatus[s] = 0;
820
+ for (const a of _aaAgents.values()) agentsByStatus[a.status]++;
821
+ const runsByStatus = {};
822
+ for (const s of Object.values(AUTOAGENT_RUN_LIFECYCLE_V2))
823
+ runsByStatus[s] = 0;
824
+ for (const r of _aaRuns.values()) runsByStatus[r.status]++;
825
+ return {
826
+ totalAutoAgentsV2: _aaAgents.size,
827
+ totalAutoAgentRunsV2: _aaRuns.size,
828
+ maxActiveAutoAgentsPerOwner: _aaMaxActivePerOwner,
829
+ maxPendingAutoAgentRunsPerAgent: _aaMaxPendingRunsPerAgent,
830
+ autoAgentIdleMs: _aaAgentIdleMs,
831
+ autoAgentRunStuckMs: _aaRunStuckMs,
832
+ agentsByStatus,
833
+ runsByStatus,
834
+ };
835
+ }
@@ -635,3 +635,342 @@ export function _resetV2State() {
635
635
  _reportStatusV2.clear();
636
636
  _statusHistoryV2.clear();
637
637
  }
638
+
639
+ // ===== V2 Surface: BI Engine governance overlay (CLI v0.135.0) =====
640
+ export const BI_DATASET_MATURITY_V2 = Object.freeze({
641
+ PENDING: "pending",
642
+ ACTIVE: "active",
643
+ STALE: "stale",
644
+ ARCHIVED: "archived",
645
+ });
646
+ export const BI_QUERY_LIFECYCLE_V2 = Object.freeze({
647
+ QUEUED: "queued",
648
+ RUNNING: "running",
649
+ COMPLETED: "completed",
650
+ FAILED: "failed",
651
+ CANCELLED: "cancelled",
652
+ });
653
+
654
+ const _biDsTrans = new Map([
655
+ [
656
+ BI_DATASET_MATURITY_V2.PENDING,
657
+ new Set([BI_DATASET_MATURITY_V2.ACTIVE, BI_DATASET_MATURITY_V2.ARCHIVED]),
658
+ ],
659
+ [
660
+ BI_DATASET_MATURITY_V2.ACTIVE,
661
+ new Set([BI_DATASET_MATURITY_V2.STALE, BI_DATASET_MATURITY_V2.ARCHIVED]),
662
+ ],
663
+ [
664
+ BI_DATASET_MATURITY_V2.STALE,
665
+ new Set([BI_DATASET_MATURITY_V2.ACTIVE, BI_DATASET_MATURITY_V2.ARCHIVED]),
666
+ ],
667
+ [BI_DATASET_MATURITY_V2.ARCHIVED, new Set()],
668
+ ]);
669
+ const _biDsTerminal = new Set([BI_DATASET_MATURITY_V2.ARCHIVED]);
670
+ const _biQTrans = new Map([
671
+ [
672
+ BI_QUERY_LIFECYCLE_V2.QUEUED,
673
+ new Set([BI_QUERY_LIFECYCLE_V2.RUNNING, BI_QUERY_LIFECYCLE_V2.CANCELLED]),
674
+ ],
675
+ [
676
+ BI_QUERY_LIFECYCLE_V2.RUNNING,
677
+ new Set([
678
+ BI_QUERY_LIFECYCLE_V2.COMPLETED,
679
+ BI_QUERY_LIFECYCLE_V2.FAILED,
680
+ BI_QUERY_LIFECYCLE_V2.CANCELLED,
681
+ ]),
682
+ ],
683
+ [BI_QUERY_LIFECYCLE_V2.COMPLETED, new Set()],
684
+ [BI_QUERY_LIFECYCLE_V2.FAILED, new Set()],
685
+ [BI_QUERY_LIFECYCLE_V2.CANCELLED, new Set()],
686
+ ]);
687
+
688
+ const _biDatasets = new Map();
689
+ const _biQueries = new Map();
690
+ let _biMaxActivePerOwner = 8;
691
+ let _biMaxPendingPerDs = 10;
692
+ let _biDsIdleMs = 7 * 24 * 60 * 60 * 1000;
693
+ let _biQStuckMs = 5 * 60 * 1000;
694
+
695
+ function _biPos(n, lbl) {
696
+ const v = Math.floor(Number(n));
697
+ if (!Number.isFinite(v) || v <= 0)
698
+ throw new Error(`${lbl} must be positive integer`);
699
+ return v;
700
+ }
701
+
702
+ export function setMaxActiveBiDatasetsPerOwnerV2(n) {
703
+ _biMaxActivePerOwner = _biPos(n, "maxActiveBiDatasetsPerOwner");
704
+ }
705
+ export function getMaxActiveBiDatasetsPerOwnerV2() {
706
+ return _biMaxActivePerOwner;
707
+ }
708
+ export function setMaxPendingBiQueriesPerDatasetV2(n) {
709
+ _biMaxPendingPerDs = _biPos(n, "maxPendingBiQueriesPerDataset");
710
+ }
711
+ export function getMaxPendingBiQueriesPerDatasetV2() {
712
+ return _biMaxPendingPerDs;
713
+ }
714
+ export function setBiDatasetIdleMsV2(n) {
715
+ _biDsIdleMs = _biPos(n, "biDatasetIdleMs");
716
+ }
717
+ export function getBiDatasetIdleMsV2() {
718
+ return _biDsIdleMs;
719
+ }
720
+ export function setBiQueryStuckMsV2(n) {
721
+ _biQStuckMs = _biPos(n, "biQueryStuckMs");
722
+ }
723
+ export function getBiQueryStuckMsV2() {
724
+ return _biQStuckMs;
725
+ }
726
+
727
+ export function _resetStateBiEngineV2() {
728
+ _biDatasets.clear();
729
+ _biQueries.clear();
730
+ _biMaxActivePerOwner = 8;
731
+ _biMaxPendingPerDs = 10;
732
+ _biDsIdleMs = 7 * 24 * 60 * 60 * 1000;
733
+ _biQStuckMs = 5 * 60 * 1000;
734
+ }
735
+
736
+ export function registerBiDatasetV2({ id, owner, source, metadata } = {}) {
737
+ if (!id || typeof id !== "string") throw new Error("id is required");
738
+ if (!owner || typeof owner !== "string") throw new Error("owner is required");
739
+ if (_biDatasets.has(id))
740
+ throw new Error(`bi dataset ${id} already registered`);
741
+ const now = Date.now();
742
+ const d = {
743
+ id,
744
+ owner,
745
+ source: source || "",
746
+ status: BI_DATASET_MATURITY_V2.PENDING,
747
+ createdAt: now,
748
+ updatedAt: now,
749
+ activatedAt: null,
750
+ archivedAt: null,
751
+ lastTouchedAt: now,
752
+ metadata: { ...(metadata || {}) },
753
+ };
754
+ _biDatasets.set(id, d);
755
+ return { ...d, metadata: { ...d.metadata } };
756
+ }
757
+ function _biCheckD(from, to) {
758
+ const a = _biDsTrans.get(from);
759
+ if (!a || !a.has(to))
760
+ throw new Error(`invalid bi dataset transition ${from} → ${to}`);
761
+ }
762
+ function _biCountActive(owner) {
763
+ let n = 0;
764
+ for (const d of _biDatasets.values())
765
+ if (d.owner === owner && d.status === BI_DATASET_MATURITY_V2.ACTIVE) n++;
766
+ return n;
767
+ }
768
+
769
+ export function activateBiDatasetV2(id) {
770
+ const d = _biDatasets.get(id);
771
+ if (!d) throw new Error(`bi dataset ${id} not found`);
772
+ _biCheckD(d.status, BI_DATASET_MATURITY_V2.ACTIVE);
773
+ const recovery = d.status === BI_DATASET_MATURITY_V2.STALE;
774
+ if (!recovery) {
775
+ const a = _biCountActive(d.owner);
776
+ if (a >= _biMaxActivePerOwner)
777
+ throw new Error(
778
+ `max active bi datasets per owner (${_biMaxActivePerOwner}) reached for ${d.owner}`,
779
+ );
780
+ }
781
+ const now = Date.now();
782
+ d.status = BI_DATASET_MATURITY_V2.ACTIVE;
783
+ d.updatedAt = now;
784
+ d.lastTouchedAt = now;
785
+ if (!d.activatedAt) d.activatedAt = now;
786
+ return { ...d, metadata: { ...d.metadata } };
787
+ }
788
+ export function staleBiDatasetV2(id) {
789
+ const d = _biDatasets.get(id);
790
+ if (!d) throw new Error(`bi dataset ${id} not found`);
791
+ _biCheckD(d.status, BI_DATASET_MATURITY_V2.STALE);
792
+ d.status = BI_DATASET_MATURITY_V2.STALE;
793
+ d.updatedAt = Date.now();
794
+ return { ...d, metadata: { ...d.metadata } };
795
+ }
796
+ export function archiveBiDatasetV2(id) {
797
+ const d = _biDatasets.get(id);
798
+ if (!d) throw new Error(`bi dataset ${id} not found`);
799
+ _biCheckD(d.status, BI_DATASET_MATURITY_V2.ARCHIVED);
800
+ const now = Date.now();
801
+ d.status = BI_DATASET_MATURITY_V2.ARCHIVED;
802
+ d.updatedAt = now;
803
+ if (!d.archivedAt) d.archivedAt = now;
804
+ return { ...d, metadata: { ...d.metadata } };
805
+ }
806
+ export function touchBiDatasetV2(id) {
807
+ const d = _biDatasets.get(id);
808
+ if (!d) throw new Error(`bi dataset ${id} not found`);
809
+ if (_biDsTerminal.has(d.status))
810
+ throw new Error(`cannot touch terminal bi dataset ${id}`);
811
+ const now = Date.now();
812
+ d.lastTouchedAt = now;
813
+ d.updatedAt = now;
814
+ return { ...d, metadata: { ...d.metadata } };
815
+ }
816
+ export function getBiDatasetV2(id) {
817
+ const d = _biDatasets.get(id);
818
+ if (!d) return null;
819
+ return { ...d, metadata: { ...d.metadata } };
820
+ }
821
+ export function listBiDatasetsV2() {
822
+ return [..._biDatasets.values()].map((d) => ({
823
+ ...d,
824
+ metadata: { ...d.metadata },
825
+ }));
826
+ }
827
+
828
+ function _biCountPending(did) {
829
+ let n = 0;
830
+ for (const q of _biQueries.values())
831
+ if (
832
+ q.datasetId === did &&
833
+ (q.status === BI_QUERY_LIFECYCLE_V2.QUEUED ||
834
+ q.status === BI_QUERY_LIFECYCLE_V2.RUNNING)
835
+ )
836
+ n++;
837
+ return n;
838
+ }
839
+
840
+ export function createBiQueryV2({ id, datasetId, sql, metadata } = {}) {
841
+ if (!id || typeof id !== "string") throw new Error("id is required");
842
+ if (!datasetId || typeof datasetId !== "string")
843
+ throw new Error("datasetId is required");
844
+ if (_biQueries.has(id)) throw new Error(`bi query ${id} already exists`);
845
+ if (!_biDatasets.has(datasetId))
846
+ throw new Error(`bi dataset ${datasetId} not found`);
847
+ const pending = _biCountPending(datasetId);
848
+ if (pending >= _biMaxPendingPerDs)
849
+ throw new Error(
850
+ `max pending bi queries per dataset (${_biMaxPendingPerDs}) reached for ${datasetId}`,
851
+ );
852
+ const now = Date.now();
853
+ const q = {
854
+ id,
855
+ datasetId,
856
+ sql: sql || "",
857
+ status: BI_QUERY_LIFECYCLE_V2.QUEUED,
858
+ createdAt: now,
859
+ updatedAt: now,
860
+ startedAt: null,
861
+ settledAt: null,
862
+ metadata: { ...(metadata || {}) },
863
+ };
864
+ _biQueries.set(id, q);
865
+ return { ...q, metadata: { ...q.metadata } };
866
+ }
867
+ function _biCheckQ(from, to) {
868
+ const a = _biQTrans.get(from);
869
+ if (!a || !a.has(to))
870
+ throw new Error(`invalid bi query transition ${from} → ${to}`);
871
+ }
872
+ export function startBiQueryV2(id) {
873
+ const q = _biQueries.get(id);
874
+ if (!q) throw new Error(`bi query ${id} not found`);
875
+ _biCheckQ(q.status, BI_QUERY_LIFECYCLE_V2.RUNNING);
876
+ const now = Date.now();
877
+ q.status = BI_QUERY_LIFECYCLE_V2.RUNNING;
878
+ q.updatedAt = now;
879
+ if (!q.startedAt) q.startedAt = now;
880
+ return { ...q, metadata: { ...q.metadata } };
881
+ }
882
+ export function completeBiQueryV2(id) {
883
+ const q = _biQueries.get(id);
884
+ if (!q) throw new Error(`bi query ${id} not found`);
885
+ _biCheckQ(q.status, BI_QUERY_LIFECYCLE_V2.COMPLETED);
886
+ const now = Date.now();
887
+ q.status = BI_QUERY_LIFECYCLE_V2.COMPLETED;
888
+ q.updatedAt = now;
889
+ if (!q.settledAt) q.settledAt = now;
890
+ return { ...q, metadata: { ...q.metadata } };
891
+ }
892
+ export function failBiQueryV2(id, reason) {
893
+ const q = _biQueries.get(id);
894
+ if (!q) throw new Error(`bi query ${id} not found`);
895
+ _biCheckQ(q.status, BI_QUERY_LIFECYCLE_V2.FAILED);
896
+ const now = Date.now();
897
+ q.status = BI_QUERY_LIFECYCLE_V2.FAILED;
898
+ q.updatedAt = now;
899
+ if (!q.settledAt) q.settledAt = now;
900
+ if (reason) q.metadata.failReason = String(reason);
901
+ return { ...q, metadata: { ...q.metadata } };
902
+ }
903
+ export function cancelBiQueryV2(id, reason) {
904
+ const q = _biQueries.get(id);
905
+ if (!q) throw new Error(`bi query ${id} not found`);
906
+ _biCheckQ(q.status, BI_QUERY_LIFECYCLE_V2.CANCELLED);
907
+ const now = Date.now();
908
+ q.status = BI_QUERY_LIFECYCLE_V2.CANCELLED;
909
+ q.updatedAt = now;
910
+ if (!q.settledAt) q.settledAt = now;
911
+ if (reason) q.metadata.cancelReason = String(reason);
912
+ return { ...q, metadata: { ...q.metadata } };
913
+ }
914
+ export function getBiQueryV2(id) {
915
+ const q = _biQueries.get(id);
916
+ if (!q) return null;
917
+ return { ...q, metadata: { ...q.metadata } };
918
+ }
919
+ export function listBiQueriesV2() {
920
+ return [..._biQueries.values()].map((q) => ({
921
+ ...q,
922
+ metadata: { ...q.metadata },
923
+ }));
924
+ }
925
+
926
+ export function autoStaleIdleBiDatasetsV2({ now } = {}) {
927
+ const t = now ?? Date.now();
928
+ const flipped = [];
929
+ for (const d of _biDatasets.values())
930
+ if (
931
+ d.status === BI_DATASET_MATURITY_V2.ACTIVE &&
932
+ t - d.lastTouchedAt >= _biDsIdleMs
933
+ ) {
934
+ d.status = BI_DATASET_MATURITY_V2.STALE;
935
+ d.updatedAt = t;
936
+ flipped.push(d.id);
937
+ }
938
+ return { flipped, count: flipped.length };
939
+ }
940
+ export function autoFailStuckBiQueriesV2({ now } = {}) {
941
+ const t = now ?? Date.now();
942
+ const flipped = [];
943
+ for (const q of _biQueries.values())
944
+ if (
945
+ q.status === BI_QUERY_LIFECYCLE_V2.RUNNING &&
946
+ q.startedAt != null &&
947
+ t - q.startedAt >= _biQStuckMs
948
+ ) {
949
+ q.status = BI_QUERY_LIFECYCLE_V2.FAILED;
950
+ q.updatedAt = t;
951
+ if (!q.settledAt) q.settledAt = t;
952
+ q.metadata.failReason = "auto-fail-stuck";
953
+ flipped.push(q.id);
954
+ }
955
+ return { flipped, count: flipped.length };
956
+ }
957
+
958
+ export function getBiEngineStatsV2() {
959
+ const datasetsByStatus = {};
960
+ for (const s of Object.values(BI_DATASET_MATURITY_V2))
961
+ datasetsByStatus[s] = 0;
962
+ for (const d of _biDatasets.values()) datasetsByStatus[d.status]++;
963
+ const queriesByStatus = {};
964
+ for (const s of Object.values(BI_QUERY_LIFECYCLE_V2)) queriesByStatus[s] = 0;
965
+ for (const q of _biQueries.values()) queriesByStatus[q.status]++;
966
+ return {
967
+ totalDatasetsV2: _biDatasets.size,
968
+ totalQueriesV2: _biQueries.size,
969
+ maxActiveBiDatasetsPerOwner: _biMaxActivePerOwner,
970
+ maxPendingBiQueriesPerDataset: _biMaxPendingPerDs,
971
+ biDatasetIdleMs: _biDsIdleMs,
972
+ biQueryStuckMs: _biQStuckMs,
973
+ datasetsByStatus,
974
+ queriesByStatus,
975
+ };
976
+ }