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.
- package/bin/chainlesschain.js +0 -0
- package/package.json +1 -1
- package/src/commands/a2a.js +380 -0
- package/src/commands/agent-network.js +254 -1
- package/src/commands/audit.js +302 -0
- package/src/commands/automation.js +271 -1
- package/src/commands/bi.js +348 -0
- package/src/commands/codegen.js +224 -0
- package/src/commands/collab.js +341 -0
- package/src/commands/compliance.js +1035 -0
- package/src/commands/cowork.js +221 -0
- package/src/commands/crosschain.js +218 -0
- package/src/commands/dbevo.js +284 -0
- package/src/commands/dev.js +252 -0
- package/src/commands/did.js +358 -0
- package/src/commands/dlp.js +341 -0
- package/src/commands/encrypt.js +341 -0
- package/src/commands/evomap.js +394 -0
- package/src/commands/export.js +256 -1
- package/src/commands/federation.js +283 -0
- package/src/commands/fusion.js +258 -0
- package/src/commands/governance.js +325 -0
- package/src/commands/hardening.js +411 -0
- package/src/commands/hook.js +148 -0
- package/src/commands/import.js +252 -0
- package/src/commands/incentive.js +322 -0
- package/src/commands/inference.js +318 -0
- package/src/commands/infra.js +244 -0
- package/src/commands/instinct.js +260 -0
- package/src/commands/ipfs.js +318 -0
- package/src/commands/kg.js +387 -0
- package/src/commands/llm.js +263 -0
- package/src/commands/lowcode.js +356 -0
- package/src/commands/marketplace.js +256 -0
- package/src/commands/mcp.js +221 -0
- package/src/commands/memory.js +248 -0
- package/src/commands/multimodal.js +296 -0
- package/src/commands/nlprog.js +356 -0
- package/src/commands/note.js +244 -0
- package/src/commands/ops.js +354 -0
- package/src/commands/orchestrate.js +166 -0
- package/src/commands/org.js +277 -0
- package/src/commands/p2p.js +390 -0
- package/src/commands/perception.js +290 -0
- package/src/commands/permmem.js +251 -0
- package/src/commands/plugin-ecosystem.js +273 -0
- package/src/commands/pqc.js +393 -0
- package/src/commands/privacy.js +321 -0
- package/src/commands/quantization.js +351 -0
- package/src/commands/rcache.js +271 -0
- package/src/commands/recommend.js +340 -0
- package/src/commands/reputation.js +261 -0
- package/src/commands/runtime.js +307 -0
- package/src/commands/scim.js +262 -0
- package/src/commands/session.js +258 -0
- package/src/commands/siem.js +246 -0
- package/src/commands/skill.js +267 -1
- package/src/commands/sla.js +259 -0
- package/src/commands/social.js +256 -0
- package/src/commands/sso.js +186 -1
- package/src/commands/stress.js +230 -0
- package/src/commands/sync.js +256 -0
- package/src/commands/tech.js +338 -0
- package/src/commands/tenant.js +351 -0
- package/src/commands/terraform.js +245 -0
- package/src/commands/tokens.js +269 -0
- package/src/commands/trust.js +249 -0
- package/src/commands/wallet.js +277 -0
- package/src/commands/workflow.js +171 -0
- package/src/commands/zkp.js +335 -0
- package/src/index.js +4 -0
- package/src/lib/a2a-protocol.js +451 -0
- package/src/lib/agent-coordinator.js +325 -0
- package/src/lib/agent-network.js +387 -0
- package/src/lib/agent-router.js +395 -0
- package/src/lib/aiops.js +478 -0
- package/src/lib/app-builder.js +239 -0
- package/src/lib/audit-logger.js +379 -0
- package/src/lib/automation-engine.js +330 -0
- package/src/lib/autonomous-developer.js +350 -0
- package/src/lib/bi-engine.js +338 -0
- package/src/lib/code-agent.js +323 -0
- package/src/lib/collaboration-governance.js +364 -0
- package/src/lib/community-governance.js +436 -0
- package/src/lib/compliance-manager.js +434 -0
- package/src/lib/content-recommendation.js +469 -0
- package/src/lib/cross-chain.js +345 -0
- package/src/lib/crypto-manager.js +350 -0
- package/src/lib/dbevo.js +338 -0
- package/src/lib/decentral-infra.js +340 -0
- package/src/lib/did-manager.js +367 -0
- package/src/lib/dlp-engine.js +389 -0
- package/src/lib/evomap-federation.js +177 -0
- package/src/lib/evomap-governance.js +276 -0
- package/src/lib/federation-hardening.js +259 -0
- package/src/lib/hardening-manager.js +348 -0
- package/src/lib/hook-manager.js +380 -0
- package/src/lib/inference-network.js +330 -0
- package/src/lib/instinct-manager.js +332 -0
- package/src/lib/ipfs-storage.js +334 -0
- package/src/lib/knowledge-exporter.js +381 -0
- package/src/lib/knowledge-graph.js +432 -0
- package/src/lib/knowledge-importer.js +379 -0
- package/src/lib/llm-providers.js +391 -0
- package/src/lib/mcp-registry.js +333 -0
- package/src/lib/memory-manager.js +330 -0
- package/src/lib/multimodal.js +346 -0
- package/src/lib/nl-programming.js +343 -0
- package/src/lib/note-versioning.js +327 -0
- package/src/lib/org-manager.js +323 -0
- package/src/lib/p2p-manager.js +387 -0
- package/src/lib/perception.js +346 -0
- package/src/lib/perf-tuning.js +4 -1
- package/src/lib/permanent-memory.js +320 -0
- package/src/lib/plugin-ecosystem.js +377 -0
- package/src/lib/pqc-manager.js +368 -0
- package/src/lib/privacy-computing.js +427 -0
- package/src/lib/protocol-fusion.js +417 -0
- package/src/lib/quantization.js +325 -0
- package/src/lib/reputation-optimizer.js +299 -0
- package/src/lib/response-cache.js +327 -0
- package/src/lib/scim-manager.js +329 -0
- package/src/lib/session-manager.js +329 -0
- package/src/lib/siem-exporter.js +333 -0
- package/src/lib/skill-loader.js +377 -0
- package/src/lib/skill-marketplace.js +325 -0
- package/src/lib/sla-manager.js +275 -0
- package/src/lib/social-manager.js +326 -0
- package/src/lib/sso-manager.js +332 -0
- package/src/lib/stress-tester.js +330 -0
- package/src/lib/sync-manager.js +326 -0
- package/src/lib/tech-learning-engine.js +369 -0
- package/src/lib/tenant-saas.js +460 -0
- package/src/lib/terraform-manager.js +363 -0
- package/src/lib/threat-intel.js +335 -0
- package/src/lib/token-incentive.js +293 -0
- package/src/lib/token-tracker.js +329 -0
- package/src/lib/trust-security.js +390 -0
- package/src/lib/ueba.js +389 -0
- package/src/lib/universal-runtime.js +325 -0
- package/src/lib/wallet-manager.js +326 -0
- package/src/lib/workflow-engine.js +322 -0
- package/src/lib/zkp-engine.js +274 -0
|
@@ -946,3 +946,333 @@ export function getConfig() {
|
|
|
946
946
|
nodeTypes: Object.values(NODE_TYPE),
|
|
947
947
|
};
|
|
948
948
|
}
|
|
949
|
+
|
|
950
|
+
/* ═══════════════════════════════════════════════════════════════
|
|
951
|
+
* V2 Surface — Automation engine governance layer.
|
|
952
|
+
* Tracks per-owner automation maturity + per-automation execution
|
|
953
|
+
* lifecycle independent of legacy SQLite tables.
|
|
954
|
+
* ═══════════════════════════════════════════════════════════════ */
|
|
955
|
+
|
|
956
|
+
export const AUTOMATION_MATURITY_V2 = Object.freeze({
|
|
957
|
+
DRAFT: "draft",
|
|
958
|
+
ACTIVE: "active",
|
|
959
|
+
PAUSED: "paused",
|
|
960
|
+
RETIRED: "retired",
|
|
961
|
+
});
|
|
962
|
+
|
|
963
|
+
export const EXECUTION_LIFECYCLE_V2 = Object.freeze({
|
|
964
|
+
QUEUED: "queued",
|
|
965
|
+
RUNNING: "running",
|
|
966
|
+
SUCCEEDED: "succeeded",
|
|
967
|
+
FAILED: "failed",
|
|
968
|
+
CANCELLED: "cancelled",
|
|
969
|
+
});
|
|
970
|
+
|
|
971
|
+
const AUTOMATION_TRANSITIONS_V2 = new Map([
|
|
972
|
+
["draft", new Set(["active", "retired"])],
|
|
973
|
+
["active", new Set(["paused", "retired"])],
|
|
974
|
+
["paused", new Set(["active", "retired"])],
|
|
975
|
+
["retired", new Set()],
|
|
976
|
+
]);
|
|
977
|
+
const AUTOMATION_TERMINALS_V2 = new Set(["retired"]);
|
|
978
|
+
|
|
979
|
+
const EXECUTION_TRANSITIONS_V2 = new Map([
|
|
980
|
+
["queued", new Set(["running", "cancelled"])],
|
|
981
|
+
["running", new Set(["succeeded", "failed", "cancelled"])],
|
|
982
|
+
["succeeded", new Set()],
|
|
983
|
+
["failed", new Set()],
|
|
984
|
+
["cancelled", new Set()],
|
|
985
|
+
]);
|
|
986
|
+
const EXECUTION_TERMINALS_V2 = new Set(["succeeded", "failed", "cancelled"]);
|
|
987
|
+
|
|
988
|
+
export const AUTOMATION_DEFAULT_MAX_ACTIVE_PER_OWNER = 20;
|
|
989
|
+
export const AUTOMATION_DEFAULT_MAX_RUNNING_PER_AUTOMATION = 3;
|
|
990
|
+
export const AUTOMATION_DEFAULT_AUTOMATION_IDLE_MS = 1000 * 60 * 60 * 24 * 14; // 14 days
|
|
991
|
+
export const AUTOMATION_DEFAULT_EXECUTION_STUCK_MS = 1000 * 60 * 30; // 30 min
|
|
992
|
+
|
|
993
|
+
const _automationsV2 = new Map();
|
|
994
|
+
const _executionsV2 = new Map();
|
|
995
|
+
let _maxActiveAutomationsPerOwnerV2 = AUTOMATION_DEFAULT_MAX_ACTIVE_PER_OWNER;
|
|
996
|
+
let _maxRunningExecutionsPerAutomationV2 =
|
|
997
|
+
AUTOMATION_DEFAULT_MAX_RUNNING_PER_AUTOMATION;
|
|
998
|
+
let _automationIdleMsV2 = AUTOMATION_DEFAULT_AUTOMATION_IDLE_MS;
|
|
999
|
+
let _executionStuckMsV2 = AUTOMATION_DEFAULT_EXECUTION_STUCK_MS;
|
|
1000
|
+
|
|
1001
|
+
function _posIntAutomationV2(n, label) {
|
|
1002
|
+
const v = Math.floor(Number(n));
|
|
1003
|
+
if (!Number.isFinite(v) || v <= 0)
|
|
1004
|
+
throw new Error(`${label} must be a positive integer`);
|
|
1005
|
+
return v;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
export function getMaxActiveAutomationsPerOwnerV2() {
|
|
1009
|
+
return _maxActiveAutomationsPerOwnerV2;
|
|
1010
|
+
}
|
|
1011
|
+
export function setMaxActiveAutomationsPerOwnerV2(n) {
|
|
1012
|
+
_maxActiveAutomationsPerOwnerV2 = _posIntAutomationV2(
|
|
1013
|
+
n,
|
|
1014
|
+
"maxActiveAutomationsPerOwner",
|
|
1015
|
+
);
|
|
1016
|
+
}
|
|
1017
|
+
export function getMaxRunningExecutionsPerAutomationV2() {
|
|
1018
|
+
return _maxRunningExecutionsPerAutomationV2;
|
|
1019
|
+
}
|
|
1020
|
+
export function setMaxRunningExecutionsPerAutomationV2(n) {
|
|
1021
|
+
_maxRunningExecutionsPerAutomationV2 = _posIntAutomationV2(
|
|
1022
|
+
n,
|
|
1023
|
+
"maxRunningExecutionsPerAutomation",
|
|
1024
|
+
);
|
|
1025
|
+
}
|
|
1026
|
+
export function getAutomationIdleMsV2() {
|
|
1027
|
+
return _automationIdleMsV2;
|
|
1028
|
+
}
|
|
1029
|
+
export function setAutomationIdleMsV2(n) {
|
|
1030
|
+
_automationIdleMsV2 = _posIntAutomationV2(n, "automationIdleMs");
|
|
1031
|
+
}
|
|
1032
|
+
export function getExecutionStuckMsV2() {
|
|
1033
|
+
return _executionStuckMsV2;
|
|
1034
|
+
}
|
|
1035
|
+
export function setExecutionStuckMsV2(n) {
|
|
1036
|
+
_executionStuckMsV2 = _posIntAutomationV2(n, "executionStuckMs");
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
export function getActiveAutomationCountV2(ownerId) {
|
|
1040
|
+
let n = 0;
|
|
1041
|
+
for (const a of _automationsV2.values()) {
|
|
1042
|
+
if (a.ownerId === ownerId && a.status === "active") n += 1;
|
|
1043
|
+
}
|
|
1044
|
+
return n;
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
export function getRunningExecutionCountV2(automationId) {
|
|
1048
|
+
let n = 0;
|
|
1049
|
+
for (const e of _executionsV2.values()) {
|
|
1050
|
+
if (e.automationId === automationId && e.status === "running") n += 1;
|
|
1051
|
+
}
|
|
1052
|
+
return n;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
function _copyAutomationV2(a) {
|
|
1056
|
+
return { ...a, metadata: { ...a.metadata } };
|
|
1057
|
+
}
|
|
1058
|
+
function _copyExecutionV2(e) {
|
|
1059
|
+
return { ...e, metadata: { ...e.metadata } };
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
export function registerAutomationV2(
|
|
1063
|
+
id,
|
|
1064
|
+
{ ownerId, name, metadata = {}, now = Date.now() } = {},
|
|
1065
|
+
) {
|
|
1066
|
+
if (!id || typeof id !== "string") throw new Error("id must be a string");
|
|
1067
|
+
if (!ownerId || typeof ownerId !== "string")
|
|
1068
|
+
throw new Error("ownerId must be a string");
|
|
1069
|
+
if (!name || typeof name !== "string")
|
|
1070
|
+
throw new Error("name must be a string");
|
|
1071
|
+
if (_automationsV2.has(id))
|
|
1072
|
+
throw new Error(`automation ${id} already exists`);
|
|
1073
|
+
const a = {
|
|
1074
|
+
id,
|
|
1075
|
+
ownerId,
|
|
1076
|
+
name,
|
|
1077
|
+
status: "draft",
|
|
1078
|
+
createdAt: now,
|
|
1079
|
+
lastSeenAt: now,
|
|
1080
|
+
activatedAt: null,
|
|
1081
|
+
retiredAt: null,
|
|
1082
|
+
metadata: { ...metadata },
|
|
1083
|
+
};
|
|
1084
|
+
_automationsV2.set(id, a);
|
|
1085
|
+
return _copyAutomationV2(a);
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
export function getAutomationV2(id) {
|
|
1089
|
+
const a = _automationsV2.get(id);
|
|
1090
|
+
return a ? _copyAutomationV2(a) : null;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
export function listAutomationsV2({ ownerId, status } = {}) {
|
|
1094
|
+
const out = [];
|
|
1095
|
+
for (const a of _automationsV2.values()) {
|
|
1096
|
+
if (ownerId && a.ownerId !== ownerId) continue;
|
|
1097
|
+
if (status && a.status !== status) continue;
|
|
1098
|
+
out.push(_copyAutomationV2(a));
|
|
1099
|
+
}
|
|
1100
|
+
return out;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
export function setAutomationStatusV2(id, next, { now = Date.now() } = {}) {
|
|
1104
|
+
const a = _automationsV2.get(id);
|
|
1105
|
+
if (!a) throw new Error(`automation ${id} not found`);
|
|
1106
|
+
if (!AUTOMATION_TRANSITIONS_V2.has(next))
|
|
1107
|
+
throw new Error(`unknown automation status: ${next}`);
|
|
1108
|
+
if (AUTOMATION_TERMINALS_V2.has(a.status))
|
|
1109
|
+
throw new Error(`automation ${id} is in terminal state ${a.status}`);
|
|
1110
|
+
const allowed = AUTOMATION_TRANSITIONS_V2.get(a.status);
|
|
1111
|
+
if (!allowed.has(next))
|
|
1112
|
+
throw new Error(`cannot transition automation from ${a.status} to ${next}`);
|
|
1113
|
+
if (next === "active") {
|
|
1114
|
+
if (a.status === "draft") {
|
|
1115
|
+
const count = getActiveAutomationCountV2(a.ownerId);
|
|
1116
|
+
if (count >= _maxActiveAutomationsPerOwnerV2)
|
|
1117
|
+
throw new Error(
|
|
1118
|
+
`owner ${a.ownerId} already at active-automation cap (${_maxActiveAutomationsPerOwnerV2})`,
|
|
1119
|
+
);
|
|
1120
|
+
}
|
|
1121
|
+
if (!a.activatedAt) a.activatedAt = now;
|
|
1122
|
+
}
|
|
1123
|
+
if (next === "retired" && !a.retiredAt) a.retiredAt = now;
|
|
1124
|
+
a.status = next;
|
|
1125
|
+
a.lastSeenAt = now;
|
|
1126
|
+
return _copyAutomationV2(a);
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
export function activateAutomationV2(id, opts) {
|
|
1130
|
+
return setAutomationStatusV2(id, "active", opts);
|
|
1131
|
+
}
|
|
1132
|
+
export function pauseAutomationV2(id, opts) {
|
|
1133
|
+
return setAutomationStatusV2(id, "paused", opts);
|
|
1134
|
+
}
|
|
1135
|
+
export function retireAutomationV2(id, opts) {
|
|
1136
|
+
return setAutomationStatusV2(id, "retired", opts);
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
export function touchAutomationV2(id, { now = Date.now() } = {}) {
|
|
1140
|
+
const a = _automationsV2.get(id);
|
|
1141
|
+
if (!a) throw new Error(`automation ${id} not found`);
|
|
1142
|
+
a.lastSeenAt = now;
|
|
1143
|
+
return _copyAutomationV2(a);
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
export function createExecutionV2(
|
|
1147
|
+
id,
|
|
1148
|
+
{ automationId, metadata = {}, now = Date.now() } = {},
|
|
1149
|
+
) {
|
|
1150
|
+
if (!id || typeof id !== "string") throw new Error("id must be a string");
|
|
1151
|
+
if (!automationId || typeof automationId !== "string")
|
|
1152
|
+
throw new Error("automationId must be a string");
|
|
1153
|
+
if (_executionsV2.has(id)) throw new Error(`execution ${id} already exists`);
|
|
1154
|
+
const e = {
|
|
1155
|
+
id,
|
|
1156
|
+
automationId,
|
|
1157
|
+
status: "queued",
|
|
1158
|
+
createdAt: now,
|
|
1159
|
+
lastSeenAt: now,
|
|
1160
|
+
startedAt: null,
|
|
1161
|
+
settledAt: null,
|
|
1162
|
+
metadata: { ...metadata },
|
|
1163
|
+
};
|
|
1164
|
+
_executionsV2.set(id, e);
|
|
1165
|
+
return _copyExecutionV2(e);
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
export function getExecutionV2(id) {
|
|
1169
|
+
const e = _executionsV2.get(id);
|
|
1170
|
+
return e ? _copyExecutionV2(e) : null;
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
export function listExecutionsV2({ automationId, status } = {}) {
|
|
1174
|
+
const out = [];
|
|
1175
|
+
for (const e of _executionsV2.values()) {
|
|
1176
|
+
if (automationId && e.automationId !== automationId) continue;
|
|
1177
|
+
if (status && e.status !== status) continue;
|
|
1178
|
+
out.push(_copyExecutionV2(e));
|
|
1179
|
+
}
|
|
1180
|
+
return out;
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
export function setExecutionStatusV2(id, next, { now = Date.now() } = {}) {
|
|
1184
|
+
const e = _executionsV2.get(id);
|
|
1185
|
+
if (!e) throw new Error(`execution ${id} not found`);
|
|
1186
|
+
if (!EXECUTION_TRANSITIONS_V2.has(next))
|
|
1187
|
+
throw new Error(`unknown execution status: ${next}`);
|
|
1188
|
+
if (EXECUTION_TERMINALS_V2.has(e.status))
|
|
1189
|
+
throw new Error(`execution ${id} is in terminal state ${e.status}`);
|
|
1190
|
+
const allowed = EXECUTION_TRANSITIONS_V2.get(e.status);
|
|
1191
|
+
if (!allowed.has(next))
|
|
1192
|
+
throw new Error(`cannot transition execution from ${e.status} to ${next}`);
|
|
1193
|
+
if (next === "running") {
|
|
1194
|
+
const count = getRunningExecutionCountV2(e.automationId);
|
|
1195
|
+
if (count >= _maxRunningExecutionsPerAutomationV2)
|
|
1196
|
+
throw new Error(
|
|
1197
|
+
`automation ${e.automationId} already at running-execution cap (${_maxRunningExecutionsPerAutomationV2})`,
|
|
1198
|
+
);
|
|
1199
|
+
if (!e.startedAt) e.startedAt = now;
|
|
1200
|
+
}
|
|
1201
|
+
if (EXECUTION_TERMINALS_V2.has(next) && !e.settledAt) e.settledAt = now;
|
|
1202
|
+
e.status = next;
|
|
1203
|
+
e.lastSeenAt = now;
|
|
1204
|
+
return _copyExecutionV2(e);
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
export function startExecutionV2(id, opts) {
|
|
1208
|
+
return setExecutionStatusV2(id, "running", opts);
|
|
1209
|
+
}
|
|
1210
|
+
export function succeedExecutionV2(id, opts) {
|
|
1211
|
+
return setExecutionStatusV2(id, "succeeded", opts);
|
|
1212
|
+
}
|
|
1213
|
+
export function failExecutionV2(id, opts) {
|
|
1214
|
+
return setExecutionStatusV2(id, "failed", opts);
|
|
1215
|
+
}
|
|
1216
|
+
export function cancelExecutionV2(id, opts) {
|
|
1217
|
+
return setExecutionStatusV2(id, "cancelled", opts);
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
export function autoPauseIdleAutomationsV2({ now = Date.now() } = {}) {
|
|
1221
|
+
const flipped = [];
|
|
1222
|
+
for (const a of _automationsV2.values()) {
|
|
1223
|
+
if (a.status !== "active") continue;
|
|
1224
|
+
if (now - a.lastSeenAt > _automationIdleMsV2) {
|
|
1225
|
+
a.status = "paused";
|
|
1226
|
+
a.lastSeenAt = now;
|
|
1227
|
+
flipped.push(_copyAutomationV2(a));
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
return flipped;
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
export function autoFailStuckExecutionsV2({ now = Date.now() } = {}) {
|
|
1234
|
+
const flipped = [];
|
|
1235
|
+
for (const e of _executionsV2.values()) {
|
|
1236
|
+
if (e.status !== "running") continue;
|
|
1237
|
+
if (now - e.lastSeenAt > _executionStuckMsV2) {
|
|
1238
|
+
e.status = "failed";
|
|
1239
|
+
e.lastSeenAt = now;
|
|
1240
|
+
if (!e.settledAt) e.settledAt = now;
|
|
1241
|
+
flipped.push(_copyExecutionV2(e));
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
return flipped;
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
export function getAutomationEngineStatsV2() {
|
|
1248
|
+
const automationsByStatus = {};
|
|
1249
|
+
for (const v of Object.values(AUTOMATION_MATURITY_V2))
|
|
1250
|
+
automationsByStatus[v] = 0;
|
|
1251
|
+
for (const a of _automationsV2.values()) automationsByStatus[a.status] += 1;
|
|
1252
|
+
|
|
1253
|
+
const executionsByStatus = {};
|
|
1254
|
+
for (const v of Object.values(EXECUTION_LIFECYCLE_V2))
|
|
1255
|
+
executionsByStatus[v] = 0;
|
|
1256
|
+
for (const e of _executionsV2.values()) executionsByStatus[e.status] += 1;
|
|
1257
|
+
|
|
1258
|
+
return {
|
|
1259
|
+
totalAutomationsV2: _automationsV2.size,
|
|
1260
|
+
totalExecutionsV2: _executionsV2.size,
|
|
1261
|
+
maxActiveAutomationsPerOwner: _maxActiveAutomationsPerOwnerV2,
|
|
1262
|
+
maxRunningExecutionsPerAutomation: _maxRunningExecutionsPerAutomationV2,
|
|
1263
|
+
automationIdleMs: _automationIdleMsV2,
|
|
1264
|
+
executionStuckMs: _executionStuckMsV2,
|
|
1265
|
+
automationsByStatus,
|
|
1266
|
+
executionsByStatus,
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
export function _resetStateAutomationEngineV2() {
|
|
1271
|
+
_automationsV2.clear();
|
|
1272
|
+
_executionsV2.clear();
|
|
1273
|
+
_maxActiveAutomationsPerOwnerV2 = AUTOMATION_DEFAULT_MAX_ACTIVE_PER_OWNER;
|
|
1274
|
+
_maxRunningExecutionsPerAutomationV2 =
|
|
1275
|
+
AUTOMATION_DEFAULT_MAX_RUNNING_PER_AUTOMATION;
|
|
1276
|
+
_automationIdleMsV2 = AUTOMATION_DEFAULT_AUTOMATION_IDLE_MS;
|
|
1277
|
+
_executionStuckMsV2 = AUTOMATION_DEFAULT_EXECUTION_STUCK_MS;
|
|
1278
|
+
}
|
|
@@ -522,3 +522,353 @@ export function _resetState() {
|
|
|
522
522
|
_adrs.clear();
|
|
523
523
|
_seq = 0;
|
|
524
524
|
}
|
|
525
|
+
|
|
526
|
+
/* ── V2 Surface (Autonomous Developer) ─────────────────────
|
|
527
|
+
* Strictly additive. Two parallel state machines:
|
|
528
|
+
* - ADR maturity (4 states, superseded terminal)
|
|
529
|
+
* - Dev session V2 lifecycle (5 states, 3 terminals)
|
|
530
|
+
* Per-author active-ADR cap + per-developer running-session cap.
|
|
531
|
+
* Auto-flip: stale draft ADRs → superseded; stuck running sessions → failed.
|
|
532
|
+
*/
|
|
533
|
+
|
|
534
|
+
export const ADR_MATURITY_V2 = Object.freeze({
|
|
535
|
+
DRAFT: "draft",
|
|
536
|
+
ACCEPTED: "accepted",
|
|
537
|
+
DEPRECATED: "deprecated",
|
|
538
|
+
SUPERSEDED: "superseded",
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
export const DEV_SESSION_V2 = Object.freeze({
|
|
542
|
+
QUEUED: "queued",
|
|
543
|
+
RUNNING: "running",
|
|
544
|
+
COMPLETED: "completed",
|
|
545
|
+
FAILED: "failed",
|
|
546
|
+
CANCELED: "canceled",
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
const _ADR_TRANSITIONS_V2 = new Map([
|
|
550
|
+
[
|
|
551
|
+
ADR_MATURITY_V2.DRAFT,
|
|
552
|
+
new Set([ADR_MATURITY_V2.ACCEPTED, ADR_MATURITY_V2.SUPERSEDED]),
|
|
553
|
+
],
|
|
554
|
+
[
|
|
555
|
+
ADR_MATURITY_V2.ACCEPTED,
|
|
556
|
+
new Set([ADR_MATURITY_V2.DEPRECATED, ADR_MATURITY_V2.SUPERSEDED]),
|
|
557
|
+
],
|
|
558
|
+
[
|
|
559
|
+
ADR_MATURITY_V2.DEPRECATED,
|
|
560
|
+
new Set([ADR_MATURITY_V2.ACCEPTED, ADR_MATURITY_V2.SUPERSEDED]),
|
|
561
|
+
],
|
|
562
|
+
]);
|
|
563
|
+
const _ADR_TERMINAL_V2 = new Set([ADR_MATURITY_V2.SUPERSEDED]);
|
|
564
|
+
|
|
565
|
+
const _SESSION_TRANSITIONS_V2 = new Map([
|
|
566
|
+
[
|
|
567
|
+
DEV_SESSION_V2.QUEUED,
|
|
568
|
+
new Set([
|
|
569
|
+
DEV_SESSION_V2.RUNNING,
|
|
570
|
+
DEV_SESSION_V2.CANCELED,
|
|
571
|
+
DEV_SESSION_V2.FAILED,
|
|
572
|
+
]),
|
|
573
|
+
],
|
|
574
|
+
[
|
|
575
|
+
DEV_SESSION_V2.RUNNING,
|
|
576
|
+
new Set([
|
|
577
|
+
DEV_SESSION_V2.COMPLETED,
|
|
578
|
+
DEV_SESSION_V2.FAILED,
|
|
579
|
+
DEV_SESSION_V2.CANCELED,
|
|
580
|
+
]),
|
|
581
|
+
],
|
|
582
|
+
]);
|
|
583
|
+
const _SESSION_TERMINAL_V2 = new Set([
|
|
584
|
+
DEV_SESSION_V2.COMPLETED,
|
|
585
|
+
DEV_SESSION_V2.FAILED,
|
|
586
|
+
DEV_SESSION_V2.CANCELED,
|
|
587
|
+
]);
|
|
588
|
+
|
|
589
|
+
export const AD_DEFAULT_MAX_ACTIVE_ADRS_PER_AUTHOR = 20;
|
|
590
|
+
export const AD_DEFAULT_MAX_RUNNING_SESSIONS_PER_DEVELOPER = 3;
|
|
591
|
+
export const AD_DEFAULT_ADR_STALE_MS = 90 * 86400000;
|
|
592
|
+
export const AD_DEFAULT_SESSION_STUCK_MS = 2 * 3600000;
|
|
593
|
+
|
|
594
|
+
let _adMaxActiveAdrsPerAuthor = AD_DEFAULT_MAX_ACTIVE_ADRS_PER_AUTHOR;
|
|
595
|
+
let _adMaxRunningSessionsPerDeveloper =
|
|
596
|
+
AD_DEFAULT_MAX_RUNNING_SESSIONS_PER_DEVELOPER;
|
|
597
|
+
let _adAdrStaleMs = AD_DEFAULT_ADR_STALE_MS;
|
|
598
|
+
let _adSessionStuckMs = AD_DEFAULT_SESSION_STUCK_MS;
|
|
599
|
+
|
|
600
|
+
const _adrsV2 = new Map();
|
|
601
|
+
const _sessionsV2 = new Map();
|
|
602
|
+
|
|
603
|
+
function _positiveIntV2(n, label) {
|
|
604
|
+
const f = Math.floor(n);
|
|
605
|
+
if (!Number.isFinite(f) || f <= 0)
|
|
606
|
+
throw new Error(`${label} must be a positive integer`);
|
|
607
|
+
return f;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
function _now() {
|
|
611
|
+
return Date.now();
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
export function getMaxActiveAdrsPerAuthor() {
|
|
615
|
+
return _adMaxActiveAdrsPerAuthor;
|
|
616
|
+
}
|
|
617
|
+
export function setMaxActiveAdrsPerAuthor(n) {
|
|
618
|
+
_adMaxActiveAdrsPerAuthor = _positiveIntV2(n, "maxActiveAdrsPerAuthor");
|
|
619
|
+
return _adMaxActiveAdrsPerAuthor;
|
|
620
|
+
}
|
|
621
|
+
export function getMaxRunningSessionsPerDeveloper() {
|
|
622
|
+
return _adMaxRunningSessionsPerDeveloper;
|
|
623
|
+
}
|
|
624
|
+
export function setMaxRunningSessionsPerDeveloper(n) {
|
|
625
|
+
_adMaxRunningSessionsPerDeveloper = _positiveIntV2(
|
|
626
|
+
n,
|
|
627
|
+
"maxRunningSessionsPerDeveloper",
|
|
628
|
+
);
|
|
629
|
+
return _adMaxRunningSessionsPerDeveloper;
|
|
630
|
+
}
|
|
631
|
+
export function getAdrStaleMs() {
|
|
632
|
+
return _adAdrStaleMs;
|
|
633
|
+
}
|
|
634
|
+
export function setAdrStaleMs(n) {
|
|
635
|
+
_adAdrStaleMs = _positiveIntV2(n, "adrStaleMs");
|
|
636
|
+
return _adAdrStaleMs;
|
|
637
|
+
}
|
|
638
|
+
export function getSessionStuckMs() {
|
|
639
|
+
return _adSessionStuckMs;
|
|
640
|
+
}
|
|
641
|
+
export function setSessionStuckMs(n) {
|
|
642
|
+
_adSessionStuckMs = _positiveIntV2(n, "sessionStuckMs");
|
|
643
|
+
return _adSessionStuckMs;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
export function getActiveAdrCount(author) {
|
|
647
|
+
let c = 0;
|
|
648
|
+
for (const a of _adrsV2.values()) {
|
|
649
|
+
if (_ADR_TERMINAL_V2.has(a.status)) continue;
|
|
650
|
+
if (author !== undefined && a.author !== author) continue;
|
|
651
|
+
c++;
|
|
652
|
+
}
|
|
653
|
+
return c;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
export function getRunningSessionCount(developer) {
|
|
657
|
+
let c = 0;
|
|
658
|
+
for (const s of _sessionsV2.values()) {
|
|
659
|
+
if (s.status !== DEV_SESSION_V2.RUNNING) continue;
|
|
660
|
+
if (developer !== undefined && s.developer !== developer) continue;
|
|
661
|
+
c++;
|
|
662
|
+
}
|
|
663
|
+
return c;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
export function createAdrV2({
|
|
667
|
+
id,
|
|
668
|
+
author,
|
|
669
|
+
title,
|
|
670
|
+
initialStatus,
|
|
671
|
+
metadata,
|
|
672
|
+
} = {}) {
|
|
673
|
+
if (!id) throw new Error("id required");
|
|
674
|
+
if (!author) throw new Error("author required");
|
|
675
|
+
if (!title) throw new Error("title required");
|
|
676
|
+
if (_adrsV2.has(id)) throw new Error(`ADR ${id} already exists`);
|
|
677
|
+
const status = initialStatus ?? ADR_MATURITY_V2.DRAFT;
|
|
678
|
+
if (!Object.values(ADR_MATURITY_V2).includes(status))
|
|
679
|
+
throw new Error(`invalid initial status ${status}`);
|
|
680
|
+
if (
|
|
681
|
+
!_ADR_TERMINAL_V2.has(status) &&
|
|
682
|
+
getActiveAdrCount(author) >= _adMaxActiveAdrsPerAuthor
|
|
683
|
+
)
|
|
684
|
+
throw new Error(`author ${author} active ADR cap reached`);
|
|
685
|
+
const now = _now();
|
|
686
|
+
const a = {
|
|
687
|
+
id,
|
|
688
|
+
author,
|
|
689
|
+
title,
|
|
690
|
+
status,
|
|
691
|
+
metadata: metadata ? { ...metadata } : {},
|
|
692
|
+
createdAt: now,
|
|
693
|
+
updatedAt: now,
|
|
694
|
+
acceptedAt: status === ADR_MATURITY_V2.ACCEPTED ? now : null,
|
|
695
|
+
};
|
|
696
|
+
_adrsV2.set(id, a);
|
|
697
|
+
return { ...a, metadata: { ...a.metadata } };
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
export function getAdrV2(id) {
|
|
701
|
+
const a = _adrsV2.get(id);
|
|
702
|
+
return a ? { ...a, metadata: { ...a.metadata } } : null;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
export function listAdrsV2({ author, status } = {}) {
|
|
706
|
+
const out = [];
|
|
707
|
+
for (const a of _adrsV2.values()) {
|
|
708
|
+
if (author !== undefined && a.author !== author) continue;
|
|
709
|
+
if (status !== undefined && a.status !== status) continue;
|
|
710
|
+
out.push({ ...a, metadata: { ...a.metadata } });
|
|
711
|
+
}
|
|
712
|
+
return out;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
export function setAdrMaturityV2(id, nextStatus, { reason, metadata } = {}) {
|
|
716
|
+
const a = _adrsV2.get(id);
|
|
717
|
+
if (!a) throw new Error(`ADR ${id} not found`);
|
|
718
|
+
if (_ADR_TERMINAL_V2.has(a.status))
|
|
719
|
+
throw new Error(`ADR ${id} is terminal (${a.status})`);
|
|
720
|
+
const allowed = _ADR_TRANSITIONS_V2.get(a.status);
|
|
721
|
+
if (!allowed || !allowed.has(nextStatus))
|
|
722
|
+
throw new Error(`illegal transition ${a.status} → ${nextStatus}`);
|
|
723
|
+
a.status = nextStatus;
|
|
724
|
+
a.updatedAt = _now();
|
|
725
|
+
if (reason !== undefined) a.reason = reason;
|
|
726
|
+
if (metadata) a.metadata = { ...a.metadata, ...metadata };
|
|
727
|
+
if (nextStatus === ADR_MATURITY_V2.ACCEPTED && !a.acceptedAt)
|
|
728
|
+
a.acceptedAt = a.updatedAt;
|
|
729
|
+
return { ...a, metadata: { ...a.metadata } };
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
export function acceptAdr(id, opts) {
|
|
733
|
+
return setAdrMaturityV2(id, ADR_MATURITY_V2.ACCEPTED, opts);
|
|
734
|
+
}
|
|
735
|
+
export function deprecateAdr(id, opts) {
|
|
736
|
+
return setAdrMaturityV2(id, ADR_MATURITY_V2.DEPRECATED, opts);
|
|
737
|
+
}
|
|
738
|
+
export function supersedeAdr(id, opts) {
|
|
739
|
+
return setAdrMaturityV2(id, ADR_MATURITY_V2.SUPERSEDED, opts);
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
export function enqueueSessionV2({ id, developer, goal, metadata } = {}) {
|
|
743
|
+
if (!id) throw new Error("id required");
|
|
744
|
+
if (!developer) throw new Error("developer required");
|
|
745
|
+
if (!goal) throw new Error("goal required");
|
|
746
|
+
if (_sessionsV2.has(id)) throw new Error(`session ${id} already exists`);
|
|
747
|
+
const now = _now();
|
|
748
|
+
const s = {
|
|
749
|
+
id,
|
|
750
|
+
developer,
|
|
751
|
+
goal,
|
|
752
|
+
status: DEV_SESSION_V2.QUEUED,
|
|
753
|
+
metadata: metadata ? { ...metadata } : {},
|
|
754
|
+
createdAt: now,
|
|
755
|
+
updatedAt: now,
|
|
756
|
+
startedAt: null,
|
|
757
|
+
};
|
|
758
|
+
_sessionsV2.set(id, s);
|
|
759
|
+
return { ...s, metadata: { ...s.metadata } };
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
export function getSessionV2(id) {
|
|
763
|
+
const s = _sessionsV2.get(id);
|
|
764
|
+
return s ? { ...s, metadata: { ...s.metadata } } : null;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
export function listSessionsV2({ developer, status } = {}) {
|
|
768
|
+
const out = [];
|
|
769
|
+
for (const s of _sessionsV2.values()) {
|
|
770
|
+
if (developer !== undefined && s.developer !== developer) continue;
|
|
771
|
+
if (status !== undefined && s.status !== status) continue;
|
|
772
|
+
out.push({ ...s, metadata: { ...s.metadata } });
|
|
773
|
+
}
|
|
774
|
+
return out;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
export function setSessionStatusV2(id, nextStatus, { reason, metadata } = {}) {
|
|
778
|
+
const s = _sessionsV2.get(id);
|
|
779
|
+
if (!s) throw new Error(`session ${id} not found`);
|
|
780
|
+
if (_SESSION_TERMINAL_V2.has(s.status))
|
|
781
|
+
throw new Error(`session ${id} is terminal (${s.status})`);
|
|
782
|
+
const allowed = _SESSION_TRANSITIONS_V2.get(s.status);
|
|
783
|
+
if (!allowed || !allowed.has(nextStatus))
|
|
784
|
+
throw new Error(`illegal transition ${s.status} → ${nextStatus}`);
|
|
785
|
+
if (nextStatus === DEV_SESSION_V2.RUNNING) {
|
|
786
|
+
if (
|
|
787
|
+
getRunningSessionCount(s.developer) >= _adMaxRunningSessionsPerDeveloper
|
|
788
|
+
)
|
|
789
|
+
throw new Error(`developer ${s.developer} running session cap reached`);
|
|
790
|
+
}
|
|
791
|
+
s.status = nextStatus;
|
|
792
|
+
s.updatedAt = _now();
|
|
793
|
+
if (reason !== undefined) s.reason = reason;
|
|
794
|
+
if (metadata) s.metadata = { ...s.metadata, ...metadata };
|
|
795
|
+
if (nextStatus === DEV_SESSION_V2.RUNNING && !s.startedAt)
|
|
796
|
+
s.startedAt = s.updatedAt;
|
|
797
|
+
return { ...s, metadata: { ...s.metadata } };
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
export function startSessionV2(id, opts) {
|
|
801
|
+
return setSessionStatusV2(id, DEV_SESSION_V2.RUNNING, opts);
|
|
802
|
+
}
|
|
803
|
+
export function completeSessionV2(id, opts) {
|
|
804
|
+
return setSessionStatusV2(id, DEV_SESSION_V2.COMPLETED, opts);
|
|
805
|
+
}
|
|
806
|
+
export function failSessionV2(id, opts) {
|
|
807
|
+
return setSessionStatusV2(id, DEV_SESSION_V2.FAILED, opts);
|
|
808
|
+
}
|
|
809
|
+
export function cancelSessionV2(id, opts) {
|
|
810
|
+
return setSessionStatusV2(id, DEV_SESSION_V2.CANCELED, opts);
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
export function autoSupersedeStaleDrafts({ now } = {}) {
|
|
814
|
+
const cutoff = (now ?? _now()) - _adAdrStaleMs;
|
|
815
|
+
const flipped = [];
|
|
816
|
+
for (const a of _adrsV2.values()) {
|
|
817
|
+
if (a.status !== ADR_MATURITY_V2.DRAFT) continue;
|
|
818
|
+
if ((a.updatedAt ?? a.createdAt) > cutoff) continue;
|
|
819
|
+
a.status = ADR_MATURITY_V2.SUPERSEDED;
|
|
820
|
+
a.updatedAt = now ?? _now();
|
|
821
|
+
a.reason = "auto_supersede_stale_draft";
|
|
822
|
+
flipped.push(a.id);
|
|
823
|
+
}
|
|
824
|
+
return flipped;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
export function autoFailStuckSessions({ now } = {}) {
|
|
828
|
+
const cutoff = (now ?? _now()) - _adSessionStuckMs;
|
|
829
|
+
const flipped = [];
|
|
830
|
+
for (const s of _sessionsV2.values()) {
|
|
831
|
+
if (s.status !== DEV_SESSION_V2.RUNNING) continue;
|
|
832
|
+
if (!s.startedAt || s.startedAt > cutoff) continue;
|
|
833
|
+
s.status = DEV_SESSION_V2.FAILED;
|
|
834
|
+
s.updatedAt = now ?? _now();
|
|
835
|
+
s.reason = "auto_fail_stuck";
|
|
836
|
+
flipped.push(s.id);
|
|
837
|
+
}
|
|
838
|
+
return flipped;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
function _zeroByEnum(enumObj) {
|
|
842
|
+
const out = {};
|
|
843
|
+
for (const v of Object.values(enumObj)) out[v] = 0;
|
|
844
|
+
return out;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
export function getAutonomousDeveloperStatsV2() {
|
|
848
|
+
const adrs = [..._adrsV2.values()];
|
|
849
|
+
const sessions = [..._sessionsV2.values()];
|
|
850
|
+
const adrsByStatus = _zeroByEnum(ADR_MATURITY_V2);
|
|
851
|
+
for (const a of adrs) adrsByStatus[a.status]++;
|
|
852
|
+
const sessionsByStatus = _zeroByEnum(DEV_SESSION_V2);
|
|
853
|
+
for (const s of sessions) sessionsByStatus[s.status]++;
|
|
854
|
+
return {
|
|
855
|
+
totalAdrsV2: adrs.length,
|
|
856
|
+
totalSessionsV2: sessions.length,
|
|
857
|
+
maxActiveAdrsPerAuthor: _adMaxActiveAdrsPerAuthor,
|
|
858
|
+
maxRunningSessionsPerDeveloper: _adMaxRunningSessionsPerDeveloper,
|
|
859
|
+
adrStaleMs: _adAdrStaleMs,
|
|
860
|
+
sessionStuckMs: _adSessionStuckMs,
|
|
861
|
+
adrsByStatus,
|
|
862
|
+
sessionsByStatus,
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
export function _resetStateV2() {
|
|
867
|
+
_adrsV2.clear();
|
|
868
|
+
_sessionsV2.clear();
|
|
869
|
+
_adMaxActiveAdrsPerAuthor = AD_DEFAULT_MAX_ACTIVE_ADRS_PER_AUTHOR;
|
|
870
|
+
_adMaxRunningSessionsPerDeveloper =
|
|
871
|
+
AD_DEFAULT_MAX_RUNNING_SESSIONS_PER_DEVELOPER;
|
|
872
|
+
_adAdrStaleMs = AD_DEFAULT_ADR_STALE_MS;
|
|
873
|
+
_adSessionStuckMs = AD_DEFAULT_SESSION_STUCK_MS;
|
|
874
|
+
}
|