chainlesschain 0.143.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.
- package/package.json +1 -1
- package/src/commands/a2a.js +196 -28
- package/src/commands/activitypub.js +157 -27
- package/src/commands/agent.js +587 -103
- package/src/commands/audit.js +206 -0
- package/src/commands/bi.js +152 -27
- package/src/commands/bm25.js +111 -27
- package/src/commands/browse.js +190 -29
- package/src/commands/ccron.js +128 -28
- package/src/commands/chat.js +207 -0
- package/src/commands/compliance.js +414 -34
- package/src/commands/compt.js +127 -29
- package/src/commands/consol.js +8 -2
- package/src/commands/cowork.js +580 -34
- package/src/commands/crosschain.js +182 -28
- package/src/commands/dao.js +182 -28
- package/src/commands/dlp.js +172 -27
- package/src/commands/economy.js +205 -50
- package/src/commands/evolution.js +203 -50
- package/src/commands/evomap.js +182 -27
- package/src/commands/fflag.js +74 -22
- package/src/commands/git.js +177 -37
- package/src/commands/hardening.js +209 -0
- package/src/commands/hmemory.js +204 -50
- package/src/commands/incentive.js +209 -0
- package/src/commands/inference.js +170 -34
- package/src/commands/itbudget.js +149 -33
- package/src/commands/kg.js +206 -0
- package/src/commands/lowcode.js +195 -38
- package/src/commands/marketplace.js +206 -0
- package/src/commands/matrix.js +179 -27
- package/src/commands/mcpscaf.js +145 -33
- package/src/commands/meminj.js +145 -33
- package/src/commands/nostr.js +178 -27
- package/src/commands/orchestrate.js +217 -0
- package/src/commands/orchgov.js +144 -33
- package/src/commands/pdfp.js +109 -27
- package/src/commands/perf.js +169 -32
- package/src/commands/perm.js +144 -33
- package/src/commands/pipeline.js +207 -52
- package/src/commands/planmode.js +141 -32
- package/src/commands/privacy.js +203 -0
- package/src/commands/promcomp.js +111 -27
- package/src/commands/recommend.js +177 -34
- package/src/commands/reputation.js +208 -0
- package/src/commands/sandbox.js +206 -0
- package/src/commands/seshhook.js +145 -33
- package/src/commands/seshsearch.js +141 -33
- package/src/commands/seshtail.js +144 -33
- package/src/commands/seshu.js +152 -33
- package/src/commands/sganal.js +123 -29
- package/src/commands/siem.js +201 -34
- package/src/commands/sla.js +212 -0
- package/src/commands/slotfill.js +146 -33
- package/src/commands/social.js +157 -32
- package/src/commands/stress.js +206 -0
- package/src/commands/svccont.js +145 -33
- package/src/commands/terraform.js +206 -0
- package/src/commands/tms.js +171 -33
- package/src/commands/topiccls.js +146 -33
- package/src/commands/uprof.js +141 -32
- package/src/commands/vcheck.js +122 -28
- package/src/commands/webfetch.js +141 -32
- package/src/commands/zkp.js +184 -28
- package/src/index.js +40 -0
- package/src/lib/a2a-protocol.js +319 -51
- package/src/lib/activitypub-bridge.js +288 -50
- package/src/lib/agent-economy.js +304 -51
- package/src/lib/app-builder.js +279 -46
- package/src/lib/audit-logger.js +321 -0
- package/src/lib/autonomous-agent.js +284 -48
- package/src/lib/bi-engine.js +283 -49
- package/src/lib/bm25-search.js +301 -49
- package/src/lib/browser-automation.js +296 -49
- package/src/lib/chat-core.js +336 -0
- package/src/lib/claude-code-bridge.js +341 -0
- package/src/lib/compliance-framework-reporter.js +305 -51
- package/src/lib/compliance-manager.js +330 -0
- package/src/lib/compression-telemetry.js +301 -49
- package/src/lib/content-recommender.js +317 -52
- package/src/lib/cowork-cron.js +298 -49
- package/src/lib/cowork-learning.js +333 -0
- package/src/lib/cowork-task-runner.js +308 -51
- package/src/lib/cowork-workflow.js +327 -0
- package/src/lib/cross-chain.js +311 -51
- package/src/lib/dao-governance.js +280 -46
- package/src/lib/dlp-engine.js +287 -49
- package/src/lib/evolution-system.js +278 -47
- package/src/lib/evomap-manager.js +280 -46
- package/src/lib/execution-backend.js +294 -48
- package/src/lib/feature-flags.js +294 -49
- package/src/lib/git-integration.js +285 -47
- package/src/lib/hardening-manager.js +341 -0
- package/src/lib/hierarchical-memory.js +284 -48
- package/src/lib/inference-network.js +308 -51
- package/src/lib/iteration-budget.js +302 -50
- package/src/lib/knowledge-graph.js +333 -0
- package/src/lib/matrix-bridge.js +281 -47
- package/src/lib/mcp-scaffold.js +318 -54
- package/src/lib/memory-injection.js +288 -49
- package/src/lib/nostr-bridge.js +286 -49
- package/src/lib/orchestrator.js +293 -48
- package/src/lib/pdf-parser.js +298 -49
- package/src/lib/perf-tuning.js +309 -50
- package/src/lib/permission-engine.js +287 -49
- package/src/lib/pipeline-orchestrator.js +289 -49
- package/src/lib/plan-mode.js +298 -51
- package/src/lib/privacy-computing.js +335 -0
- package/src/lib/reputation-optimizer.js +340 -0
- package/src/lib/sandbox-v2.js +327 -0
- package/src/lib/service-container.js +313 -52
- package/src/lib/session-consolidator.js +296 -49
- package/src/lib/session-hooks.js +312 -53
- package/src/lib/session-search.js +304 -51
- package/src/lib/session-tail.js +288 -49
- package/src/lib/session-usage.js +298 -52
- package/src/lib/siem-exporter.js +298 -51
- package/src/lib/skill-marketplace.js +345 -0
- package/src/lib/sla-manager.js +341 -0
- package/src/lib/slot-filler.js +303 -51
- package/src/lib/social-graph-analytics.js +295 -49
- package/src/lib/social-graph.js +272 -49
- package/src/lib/stress-tester.js +342 -0
- package/src/lib/sub-agent-registry.js +302 -53
- package/src/lib/task-model-selector.js +302 -50
- package/src/lib/terraform-manager.js +333 -0
- package/src/lib/todo-manager.js +281 -47
- package/src/lib/token-incentive.js +341 -0
- package/src/lib/topic-classifier.js +297 -49
- package/src/lib/user-profile.js +294 -50
- package/src/lib/version-checker.js +304 -50
- package/src/lib/web-fetch.js +292 -51
- package/src/lib/zkp-engine.js +286 -49
|
@@ -562,3 +562,336 @@ export function getTerraformStatsV2() {
|
|
|
562
562
|
totalResources,
|
|
563
563
|
};
|
|
564
564
|
}
|
|
565
|
+
|
|
566
|
+
// =====================================================================
|
|
567
|
+
// terraform-manager V2 governance overlay (iter16)
|
|
568
|
+
// =====================================================================
|
|
569
|
+
export const TFGOV_PROFILE_MATURITY_V2 = Object.freeze({
|
|
570
|
+
PENDING: "pending",
|
|
571
|
+
ACTIVE: "active",
|
|
572
|
+
DRIFTED: "drifted",
|
|
573
|
+
ARCHIVED: "archived",
|
|
574
|
+
});
|
|
575
|
+
export const TFGOV_APPLY_LIFECYCLE_V2 = Object.freeze({
|
|
576
|
+
QUEUED: "queued",
|
|
577
|
+
APPLYING: "applying",
|
|
578
|
+
APPLIED: "applied",
|
|
579
|
+
FAILED: "failed",
|
|
580
|
+
CANCELLED: "cancelled",
|
|
581
|
+
});
|
|
582
|
+
const _tfgovPTrans = new Map([
|
|
583
|
+
[
|
|
584
|
+
TFGOV_PROFILE_MATURITY_V2.PENDING,
|
|
585
|
+
new Set([
|
|
586
|
+
TFGOV_PROFILE_MATURITY_V2.ACTIVE,
|
|
587
|
+
TFGOV_PROFILE_MATURITY_V2.ARCHIVED,
|
|
588
|
+
]),
|
|
589
|
+
],
|
|
590
|
+
[
|
|
591
|
+
TFGOV_PROFILE_MATURITY_V2.ACTIVE,
|
|
592
|
+
new Set([
|
|
593
|
+
TFGOV_PROFILE_MATURITY_V2.DRIFTED,
|
|
594
|
+
TFGOV_PROFILE_MATURITY_V2.ARCHIVED,
|
|
595
|
+
]),
|
|
596
|
+
],
|
|
597
|
+
[
|
|
598
|
+
TFGOV_PROFILE_MATURITY_V2.DRIFTED,
|
|
599
|
+
new Set([
|
|
600
|
+
TFGOV_PROFILE_MATURITY_V2.ACTIVE,
|
|
601
|
+
TFGOV_PROFILE_MATURITY_V2.ARCHIVED,
|
|
602
|
+
]),
|
|
603
|
+
],
|
|
604
|
+
[TFGOV_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
|
|
605
|
+
]);
|
|
606
|
+
const _tfgovPTerminal = new Set([TFGOV_PROFILE_MATURITY_V2.ARCHIVED]);
|
|
607
|
+
const _tfgovJTrans = new Map([
|
|
608
|
+
[
|
|
609
|
+
TFGOV_APPLY_LIFECYCLE_V2.QUEUED,
|
|
610
|
+
new Set([
|
|
611
|
+
TFGOV_APPLY_LIFECYCLE_V2.APPLYING,
|
|
612
|
+
TFGOV_APPLY_LIFECYCLE_V2.CANCELLED,
|
|
613
|
+
]),
|
|
614
|
+
],
|
|
615
|
+
[
|
|
616
|
+
TFGOV_APPLY_LIFECYCLE_V2.APPLYING,
|
|
617
|
+
new Set([
|
|
618
|
+
TFGOV_APPLY_LIFECYCLE_V2.APPLIED,
|
|
619
|
+
TFGOV_APPLY_LIFECYCLE_V2.FAILED,
|
|
620
|
+
TFGOV_APPLY_LIFECYCLE_V2.CANCELLED,
|
|
621
|
+
]),
|
|
622
|
+
],
|
|
623
|
+
[TFGOV_APPLY_LIFECYCLE_V2.APPLIED, new Set()],
|
|
624
|
+
[TFGOV_APPLY_LIFECYCLE_V2.FAILED, new Set()],
|
|
625
|
+
[TFGOV_APPLY_LIFECYCLE_V2.CANCELLED, new Set()],
|
|
626
|
+
]);
|
|
627
|
+
const _tfgovPsV2 = new Map();
|
|
628
|
+
const _tfgovJsV2 = new Map();
|
|
629
|
+
let _tfgovMaxActive = 6,
|
|
630
|
+
_tfgovMaxPending = 12,
|
|
631
|
+
_tfgovIdleMs = 30 * 24 * 60 * 60 * 1000,
|
|
632
|
+
_tfgovStuckMs = 60 * 1000;
|
|
633
|
+
function _tfgovPos(n, label) {
|
|
634
|
+
const v = Math.floor(Number(n));
|
|
635
|
+
if (!Number.isFinite(v) || v <= 0)
|
|
636
|
+
throw new Error(`${label} must be positive integer`);
|
|
637
|
+
return v;
|
|
638
|
+
}
|
|
639
|
+
function _tfgovCheckP(from, to) {
|
|
640
|
+
const a = _tfgovPTrans.get(from);
|
|
641
|
+
if (!a || !a.has(to))
|
|
642
|
+
throw new Error(`invalid tfgov profile transition ${from} → ${to}`);
|
|
643
|
+
}
|
|
644
|
+
function _tfgovCheckJ(from, to) {
|
|
645
|
+
const a = _tfgovJTrans.get(from);
|
|
646
|
+
if (!a || !a.has(to))
|
|
647
|
+
throw new Error(`invalid tfgov apply transition ${from} → ${to}`);
|
|
648
|
+
}
|
|
649
|
+
function _tfgovCountActive(owner) {
|
|
650
|
+
let c = 0;
|
|
651
|
+
for (const p of _tfgovPsV2.values())
|
|
652
|
+
if (p.owner === owner && p.status === TFGOV_PROFILE_MATURITY_V2.ACTIVE) c++;
|
|
653
|
+
return c;
|
|
654
|
+
}
|
|
655
|
+
function _tfgovCountPending(profileId) {
|
|
656
|
+
let c = 0;
|
|
657
|
+
for (const j of _tfgovJsV2.values())
|
|
658
|
+
if (
|
|
659
|
+
j.profileId === profileId &&
|
|
660
|
+
(j.status === TFGOV_APPLY_LIFECYCLE_V2.QUEUED ||
|
|
661
|
+
j.status === TFGOV_APPLY_LIFECYCLE_V2.APPLYING)
|
|
662
|
+
)
|
|
663
|
+
c++;
|
|
664
|
+
return c;
|
|
665
|
+
}
|
|
666
|
+
export function setMaxActiveTfgovProfilesPerOwnerV2(n) {
|
|
667
|
+
_tfgovMaxActive = _tfgovPos(n, "maxActiveTfgovProfilesPerOwner");
|
|
668
|
+
}
|
|
669
|
+
export function getMaxActiveTfgovProfilesPerOwnerV2() {
|
|
670
|
+
return _tfgovMaxActive;
|
|
671
|
+
}
|
|
672
|
+
export function setMaxPendingTfgovApplysPerProfileV2(n) {
|
|
673
|
+
_tfgovMaxPending = _tfgovPos(n, "maxPendingTfgovApplysPerProfile");
|
|
674
|
+
}
|
|
675
|
+
export function getMaxPendingTfgovApplysPerProfileV2() {
|
|
676
|
+
return _tfgovMaxPending;
|
|
677
|
+
}
|
|
678
|
+
export function setTfgovProfileIdleMsV2(n) {
|
|
679
|
+
_tfgovIdleMs = _tfgovPos(n, "tfgovProfileIdleMs");
|
|
680
|
+
}
|
|
681
|
+
export function getTfgovProfileIdleMsV2() {
|
|
682
|
+
return _tfgovIdleMs;
|
|
683
|
+
}
|
|
684
|
+
export function setTfgovApplyStuckMsV2(n) {
|
|
685
|
+
_tfgovStuckMs = _tfgovPos(n, "tfgovApplyStuckMs");
|
|
686
|
+
}
|
|
687
|
+
export function getTfgovApplyStuckMsV2() {
|
|
688
|
+
return _tfgovStuckMs;
|
|
689
|
+
}
|
|
690
|
+
export function _resetStateTerraformManagerV2() {
|
|
691
|
+
_tfgovPsV2.clear();
|
|
692
|
+
_tfgovJsV2.clear();
|
|
693
|
+
_tfgovMaxActive = 6;
|
|
694
|
+
_tfgovMaxPending = 12;
|
|
695
|
+
_tfgovIdleMs = 30 * 24 * 60 * 60 * 1000;
|
|
696
|
+
_tfgovStuckMs = 60 * 1000;
|
|
697
|
+
}
|
|
698
|
+
export function registerTfgovProfileV2({ id, owner, provider, metadata } = {}) {
|
|
699
|
+
if (!id || !owner) throw new Error("id and owner required");
|
|
700
|
+
if (_tfgovPsV2.has(id)) throw new Error(`tfgov profile ${id} already exists`);
|
|
701
|
+
const now = Date.now();
|
|
702
|
+
const p = {
|
|
703
|
+
id,
|
|
704
|
+
owner,
|
|
705
|
+
provider: provider || "aws",
|
|
706
|
+
status: TFGOV_PROFILE_MATURITY_V2.PENDING,
|
|
707
|
+
createdAt: now,
|
|
708
|
+
updatedAt: now,
|
|
709
|
+
lastTouchedAt: now,
|
|
710
|
+
activatedAt: null,
|
|
711
|
+
archivedAt: null,
|
|
712
|
+
metadata: { ...(metadata || {}) },
|
|
713
|
+
};
|
|
714
|
+
_tfgovPsV2.set(id, p);
|
|
715
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
716
|
+
}
|
|
717
|
+
export function activateTfgovProfileV2(id) {
|
|
718
|
+
const p = _tfgovPsV2.get(id);
|
|
719
|
+
if (!p) throw new Error(`tfgov profile ${id} not found`);
|
|
720
|
+
const isInitial = p.status === TFGOV_PROFILE_MATURITY_V2.PENDING;
|
|
721
|
+
_tfgovCheckP(p.status, TFGOV_PROFILE_MATURITY_V2.ACTIVE);
|
|
722
|
+
if (isInitial && _tfgovCountActive(p.owner) >= _tfgovMaxActive)
|
|
723
|
+
throw new Error(`max active tfgov profiles for owner ${p.owner} reached`);
|
|
724
|
+
const now = Date.now();
|
|
725
|
+
p.status = TFGOV_PROFILE_MATURITY_V2.ACTIVE;
|
|
726
|
+
p.updatedAt = now;
|
|
727
|
+
p.lastTouchedAt = now;
|
|
728
|
+
if (!p.activatedAt) p.activatedAt = now;
|
|
729
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
730
|
+
}
|
|
731
|
+
export function driftTfgovProfileV2(id) {
|
|
732
|
+
const p = _tfgovPsV2.get(id);
|
|
733
|
+
if (!p) throw new Error(`tfgov profile ${id} not found`);
|
|
734
|
+
_tfgovCheckP(p.status, TFGOV_PROFILE_MATURITY_V2.DRIFTED);
|
|
735
|
+
p.status = TFGOV_PROFILE_MATURITY_V2.DRIFTED;
|
|
736
|
+
p.updatedAt = Date.now();
|
|
737
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
738
|
+
}
|
|
739
|
+
export function archiveTfgovProfileV2(id) {
|
|
740
|
+
const p = _tfgovPsV2.get(id);
|
|
741
|
+
if (!p) throw new Error(`tfgov profile ${id} not found`);
|
|
742
|
+
_tfgovCheckP(p.status, TFGOV_PROFILE_MATURITY_V2.ARCHIVED);
|
|
743
|
+
const now = Date.now();
|
|
744
|
+
p.status = TFGOV_PROFILE_MATURITY_V2.ARCHIVED;
|
|
745
|
+
p.updatedAt = now;
|
|
746
|
+
if (!p.archivedAt) p.archivedAt = now;
|
|
747
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
748
|
+
}
|
|
749
|
+
export function touchTfgovProfileV2(id) {
|
|
750
|
+
const p = _tfgovPsV2.get(id);
|
|
751
|
+
if (!p) throw new Error(`tfgov profile ${id} not found`);
|
|
752
|
+
if (_tfgovPTerminal.has(p.status))
|
|
753
|
+
throw new Error(`cannot touch terminal tfgov profile ${id}`);
|
|
754
|
+
const now = Date.now();
|
|
755
|
+
p.lastTouchedAt = now;
|
|
756
|
+
p.updatedAt = now;
|
|
757
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
758
|
+
}
|
|
759
|
+
export function getTfgovProfileV2(id) {
|
|
760
|
+
const p = _tfgovPsV2.get(id);
|
|
761
|
+
if (!p) return null;
|
|
762
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
763
|
+
}
|
|
764
|
+
export function listTfgovProfilesV2() {
|
|
765
|
+
return [..._tfgovPsV2.values()].map((p) => ({
|
|
766
|
+
...p,
|
|
767
|
+
metadata: { ...p.metadata },
|
|
768
|
+
}));
|
|
769
|
+
}
|
|
770
|
+
export function createTfgovApplyV2({ id, profileId, resource, metadata } = {}) {
|
|
771
|
+
if (!id || !profileId) throw new Error("id and profileId required");
|
|
772
|
+
if (_tfgovJsV2.has(id)) throw new Error(`tfgov apply ${id} already exists`);
|
|
773
|
+
if (!_tfgovPsV2.has(profileId))
|
|
774
|
+
throw new Error(`tfgov profile ${profileId} not found`);
|
|
775
|
+
if (_tfgovCountPending(profileId) >= _tfgovMaxPending)
|
|
776
|
+
throw new Error(
|
|
777
|
+
`max pending tfgov applys for profile ${profileId} reached`,
|
|
778
|
+
);
|
|
779
|
+
const now = Date.now();
|
|
780
|
+
const j = {
|
|
781
|
+
id,
|
|
782
|
+
profileId,
|
|
783
|
+
resource: resource || "",
|
|
784
|
+
status: TFGOV_APPLY_LIFECYCLE_V2.QUEUED,
|
|
785
|
+
createdAt: now,
|
|
786
|
+
updatedAt: now,
|
|
787
|
+
startedAt: null,
|
|
788
|
+
settledAt: null,
|
|
789
|
+
metadata: { ...(metadata || {}) },
|
|
790
|
+
};
|
|
791
|
+
_tfgovJsV2.set(id, j);
|
|
792
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
793
|
+
}
|
|
794
|
+
export function applyingTfgovApplyV2(id) {
|
|
795
|
+
const j = _tfgovJsV2.get(id);
|
|
796
|
+
if (!j) throw new Error(`tfgov apply ${id} not found`);
|
|
797
|
+
_tfgovCheckJ(j.status, TFGOV_APPLY_LIFECYCLE_V2.APPLYING);
|
|
798
|
+
const now = Date.now();
|
|
799
|
+
j.status = TFGOV_APPLY_LIFECYCLE_V2.APPLYING;
|
|
800
|
+
j.updatedAt = now;
|
|
801
|
+
if (!j.startedAt) j.startedAt = now;
|
|
802
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
803
|
+
}
|
|
804
|
+
export function completeApplyTfgovV2(id) {
|
|
805
|
+
const j = _tfgovJsV2.get(id);
|
|
806
|
+
if (!j) throw new Error(`tfgov apply ${id} not found`);
|
|
807
|
+
_tfgovCheckJ(j.status, TFGOV_APPLY_LIFECYCLE_V2.APPLIED);
|
|
808
|
+
const now = Date.now();
|
|
809
|
+
j.status = TFGOV_APPLY_LIFECYCLE_V2.APPLIED;
|
|
810
|
+
j.updatedAt = now;
|
|
811
|
+
if (!j.settledAt) j.settledAt = now;
|
|
812
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
813
|
+
}
|
|
814
|
+
export function failTfgovApplyV2(id, reason) {
|
|
815
|
+
const j = _tfgovJsV2.get(id);
|
|
816
|
+
if (!j) throw new Error(`tfgov apply ${id} not found`);
|
|
817
|
+
_tfgovCheckJ(j.status, TFGOV_APPLY_LIFECYCLE_V2.FAILED);
|
|
818
|
+
const now = Date.now();
|
|
819
|
+
j.status = TFGOV_APPLY_LIFECYCLE_V2.FAILED;
|
|
820
|
+
j.updatedAt = now;
|
|
821
|
+
if (!j.settledAt) j.settledAt = now;
|
|
822
|
+
if (reason) j.metadata.failReason = String(reason);
|
|
823
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
824
|
+
}
|
|
825
|
+
export function cancelTfgovApplyV2(id, reason) {
|
|
826
|
+
const j = _tfgovJsV2.get(id);
|
|
827
|
+
if (!j) throw new Error(`tfgov apply ${id} not found`);
|
|
828
|
+
_tfgovCheckJ(j.status, TFGOV_APPLY_LIFECYCLE_V2.CANCELLED);
|
|
829
|
+
const now = Date.now();
|
|
830
|
+
j.status = TFGOV_APPLY_LIFECYCLE_V2.CANCELLED;
|
|
831
|
+
j.updatedAt = now;
|
|
832
|
+
if (!j.settledAt) j.settledAt = now;
|
|
833
|
+
if (reason) j.metadata.cancelReason = String(reason);
|
|
834
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
835
|
+
}
|
|
836
|
+
export function getTfgovApplyV2(id) {
|
|
837
|
+
const j = _tfgovJsV2.get(id);
|
|
838
|
+
if (!j) return null;
|
|
839
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
840
|
+
}
|
|
841
|
+
export function listTfgovApplysV2() {
|
|
842
|
+
return [..._tfgovJsV2.values()].map((j) => ({
|
|
843
|
+
...j,
|
|
844
|
+
metadata: { ...j.metadata },
|
|
845
|
+
}));
|
|
846
|
+
}
|
|
847
|
+
export function autoDriftIdleTfgovProfilesV2({ now } = {}) {
|
|
848
|
+
const t = now ?? Date.now();
|
|
849
|
+
const flipped = [];
|
|
850
|
+
for (const p of _tfgovPsV2.values())
|
|
851
|
+
if (
|
|
852
|
+
p.status === TFGOV_PROFILE_MATURITY_V2.ACTIVE &&
|
|
853
|
+
t - p.lastTouchedAt >= _tfgovIdleMs
|
|
854
|
+
) {
|
|
855
|
+
p.status = TFGOV_PROFILE_MATURITY_V2.DRIFTED;
|
|
856
|
+
p.updatedAt = t;
|
|
857
|
+
flipped.push(p.id);
|
|
858
|
+
}
|
|
859
|
+
return { flipped, count: flipped.length };
|
|
860
|
+
}
|
|
861
|
+
export function autoFailStuckTfgovApplysV2({ now } = {}) {
|
|
862
|
+
const t = now ?? Date.now();
|
|
863
|
+
const flipped = [];
|
|
864
|
+
for (const j of _tfgovJsV2.values())
|
|
865
|
+
if (
|
|
866
|
+
j.status === TFGOV_APPLY_LIFECYCLE_V2.APPLYING &&
|
|
867
|
+
j.startedAt != null &&
|
|
868
|
+
t - j.startedAt >= _tfgovStuckMs
|
|
869
|
+
) {
|
|
870
|
+
j.status = TFGOV_APPLY_LIFECYCLE_V2.FAILED;
|
|
871
|
+
j.updatedAt = t;
|
|
872
|
+
if (!j.settledAt) j.settledAt = t;
|
|
873
|
+
j.metadata.failReason = "auto-fail-stuck";
|
|
874
|
+
flipped.push(j.id);
|
|
875
|
+
}
|
|
876
|
+
return { flipped, count: flipped.length };
|
|
877
|
+
}
|
|
878
|
+
export function getTerraformManagerGovStatsV2() {
|
|
879
|
+
const profilesByStatus = {};
|
|
880
|
+
for (const v of Object.values(TFGOV_PROFILE_MATURITY_V2))
|
|
881
|
+
profilesByStatus[v] = 0;
|
|
882
|
+
for (const p of _tfgovPsV2.values()) profilesByStatus[p.status]++;
|
|
883
|
+
const applysByStatus = {};
|
|
884
|
+
for (const v of Object.values(TFGOV_APPLY_LIFECYCLE_V2))
|
|
885
|
+
applysByStatus[v] = 0;
|
|
886
|
+
for (const j of _tfgovJsV2.values()) applysByStatus[j.status]++;
|
|
887
|
+
return {
|
|
888
|
+
totalTfgovProfilesV2: _tfgovPsV2.size,
|
|
889
|
+
totalTfgovApplysV2: _tfgovJsV2.size,
|
|
890
|
+
maxActiveTfgovProfilesPerOwner: _tfgovMaxActive,
|
|
891
|
+
maxPendingTfgovApplysPerProfile: _tfgovMaxPending,
|
|
892
|
+
tfgovProfileIdleMs: _tfgovIdleMs,
|
|
893
|
+
tfgovApplyStuckMs: _tfgovStuckMs,
|
|
894
|
+
profilesByStatus,
|
|
895
|
+
applysByStatus,
|
|
896
|
+
};
|
|
897
|
+
}
|