chainlesschain 0.81.0 → 0.143.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 +62 -0
- package/src/commands/activitypub.js +61 -0
- package/src/commands/agent-network.js +254 -1
- package/src/commands/agent.js +117 -0
- package/src/commands/audit.js +302 -0
- package/src/commands/automation.js +271 -1
- package/src/commands/bi.js +61 -0
- package/src/commands/bm25.js +78 -0
- package/src/commands/browse.js +64 -0
- package/src/commands/ccron.js +78 -0
- package/src/commands/codegen.js +224 -0
- package/src/commands/collab.js +341 -0
- package/src/commands/compliance.js +1075 -0
- package/src/commands/compt.js +78 -0
- package/src/commands/consol.js +231 -0
- package/src/commands/cowork.js +263 -0
- package/src/commands/crosschain.js +62 -0
- package/src/commands/dao.js +62 -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 +61 -0
- package/src/commands/economy.js +56 -0
- package/src/commands/encrypt.js +341 -0
- package/src/commands/evolution.js +56 -0
- package/src/commands/evomap.js +61 -0
- package/src/commands/export.js +256 -1
- package/src/commands/fflag.js +178 -0
- package/src/commands/fusion.js +258 -0
- package/src/commands/git.js +45 -0
- package/src/commands/governance.js +325 -0
- package/src/commands/hardening.js +411 -0
- package/src/commands/hmemory.js +56 -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 +42 -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/itbudget.js +45 -0
- package/src/commands/kg.js +387 -0
- package/src/commands/llm.js +263 -0
- package/src/commands/lowcode.js +44 -0
- package/src/commands/matrix.js +62 -0
- package/src/commands/mcp.js +221 -0
- package/src/commands/mcpscaf.js +41 -0
- package/src/commands/meminj.js +41 -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/nostr.js +62 -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/orchgov.js +45 -0
- package/src/commands/org.js +277 -0
- package/src/commands/p2p.js +390 -0
- package/src/commands/pdfp.js +78 -0
- package/src/commands/perception.js +290 -0
- package/src/commands/perf.js +39 -0
- package/src/commands/perm.js +45 -0
- package/src/commands/permmem.js +251 -0
- package/src/commands/pipeline.js +57 -1
- package/src/commands/planmode.js +45 -0
- package/src/commands/plugin-ecosystem.js +273 -0
- package/src/commands/pqc.js +393 -0
- package/src/commands/promcomp.js +82 -0
- package/src/commands/quantization.js +351 -0
- package/src/commands/rcache.js +271 -0
- package/src/commands/recommend.js +382 -0
- package/src/commands/runtime.js +307 -0
- package/src/commands/scim.js +262 -0
- package/src/commands/seshhook.js +41 -0
- package/src/commands/seshsearch.js +41 -0
- package/src/commands/seshtail.js +41 -0
- package/src/commands/seshu.js +41 -0
- package/src/commands/session.js +258 -0
- package/src/commands/sganal.js +78 -0
- package/src/commands/siem.js +40 -0
- package/src/commands/skill.js +267 -1
- package/src/commands/slotfill.js +41 -0
- package/src/commands/social.js +290 -0
- package/src/commands/sso.js +186 -1
- package/src/commands/svccont.js +45 -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/tms.js +45 -0
- package/src/commands/tokens.js +269 -0
- package/src/commands/topiccls.js +45 -0
- package/src/commands/trust.js +249 -0
- package/src/commands/uprof.js +45 -0
- package/src/commands/vcheck.js +78 -0
- package/src/commands/wallet.js +277 -0
- package/src/commands/webfetch.js +41 -0
- package/src/commands/workflow.js +171 -0
- package/src/commands/zkp.js +62 -0
- package/src/harness/prompt-compressor.js +331 -0
- package/src/index.js +65 -1
- package/src/lib/a2a-protocol.js +105 -0
- package/src/lib/activitypub-bridge.js +105 -0
- package/src/lib/agent-coordinator.js +325 -0
- package/src/lib/agent-economy.js +105 -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 +105 -0
- package/src/lib/audit-logger.js +379 -0
- package/src/lib/automation-engine.js +330 -0
- package/src/lib/autonomous-agent.js +105 -0
- package/src/lib/autonomous-developer.js +350 -0
- package/src/lib/bi-engine.js +105 -0
- package/src/lib/bm25-search.js +81 -0
- package/src/lib/browser-automation.js +105 -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-framework-reporter.js +105 -0
- package/src/lib/compliance-manager.js +434 -0
- package/src/lib/compression-telemetry.js +81 -0
- package/src/lib/content-recommendation.js +469 -0
- package/src/lib/content-recommender.js +105 -0
- package/src/lib/cowork-cron.js +81 -0
- package/src/lib/cowork-task-runner.js +105 -0
- package/src/lib/cross-chain.js +105 -0
- package/src/lib/crypto-manager.js +350 -0
- package/src/lib/dao-governance.js +105 -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 +105 -0
- package/src/lib/evolution-system.js +105 -0
- package/src/lib/evomap-manager.js +105 -0
- package/src/lib/execution-backend.js +105 -0
- package/src/lib/feature-flags.js +85 -0
- package/src/lib/git-integration.js +105 -0
- package/src/lib/hardening-manager.js +348 -0
- package/src/lib/hierarchical-memory.js +105 -0
- package/src/lib/hook-manager.js +380 -0
- package/src/lib/inference-network.js +105 -0
- package/src/lib/instinct-manager.js +332 -0
- package/src/lib/ipfs-storage.js +334 -0
- package/src/lib/iteration-budget.js +105 -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/matrix-bridge.js +105 -0
- package/src/lib/mcp-registry.js +333 -0
- package/src/lib/mcp-scaffold.js +81 -0
- package/src/lib/memory-injection.js +81 -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/nostr-bridge.js +105 -0
- package/src/lib/note-versioning.js +327 -0
- package/src/lib/orchestrator.js +105 -0
- package/src/lib/org-manager.js +323 -0
- package/src/lib/p2p-manager.js +387 -0
- package/src/lib/pdf-parser.js +81 -0
- package/src/lib/perception.js +346 -0
- package/src/lib/perf-tuning.js +109 -1
- package/src/lib/permanent-memory.js +320 -0
- package/src/lib/permission-engine.js +81 -0
- package/src/lib/pipeline-orchestrator.js +105 -0
- package/src/lib/plan-mode.js +81 -0
- package/src/lib/plugin-ecosystem.js +377 -0
- package/src/lib/pqc-manager.js +368 -0
- package/src/lib/prompt-compressor.js +1 -10
- package/src/lib/protocol-fusion.js +417 -0
- package/src/lib/quantization.js +325 -0
- package/src/lib/response-cache.js +327 -0
- package/src/lib/scim-manager.js +329 -0
- package/src/lib/service-container.js +81 -0
- package/src/lib/session-consolidator.js +105 -0
- package/src/lib/session-hooks.js +81 -0
- package/src/lib/session-manager.js +329 -0
- package/src/lib/session-search.js +81 -0
- package/src/lib/session-tail.js +81 -0
- package/src/lib/session-usage.js +83 -0
- package/src/lib/siem-exporter.js +105 -0
- package/src/lib/skill-loader.js +377 -0
- package/src/lib/slot-filler.js +81 -0
- package/src/lib/social-graph-analytics.js +81 -0
- package/src/lib/social-graph.js +81 -0
- package/src/lib/social-manager.js +326 -0
- package/src/lib/sso-manager.js +332 -0
- package/src/lib/sub-agent-registry.js +110 -0
- package/src/lib/sync-manager.js +326 -0
- package/src/lib/task-model-selector.js +81 -0
- package/src/lib/tech-learning-engine.js +369 -0
- package/src/lib/tenant-saas.js +460 -0
- package/src/lib/threat-intel.js +335 -0
- package/src/lib/todo-manager.js +105 -0
- package/src/lib/token-incentive.js +293 -0
- package/src/lib/token-tracker.js +329 -0
- package/src/lib/topic-classifier.js +105 -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/user-profile.js +81 -0
- package/src/lib/version-checker.js +81 -0
- package/src/lib/wallet-manager.js +326 -0
- package/src/lib/web-fetch.js +81 -0
- package/src/lib/workflow-engine.js +322 -0
- package/src/lib/zkp-engine.js +105 -0
|
@@ -769,3 +769,328 @@ export function _resetState() {
|
|
|
769
769
|
startedAt: Date.now(),
|
|
770
770
|
};
|
|
771
771
|
}
|
|
772
|
+
|
|
773
|
+
/* ═════════════════════════════════════════════════════════ *
|
|
774
|
+
* Phase 63 V2 — Plugin Maturity + Runtime Task Lifecycle
|
|
775
|
+
* ═════════════════════════════════════════════════════════ */
|
|
776
|
+
|
|
777
|
+
export const PLUGIN_MATURITY_V2 = Object.freeze({
|
|
778
|
+
DRAFT: "draft",
|
|
779
|
+
ACTIVE: "active",
|
|
780
|
+
DEPRECATED: "deprecated",
|
|
781
|
+
RETIRED: "retired",
|
|
782
|
+
});
|
|
783
|
+
|
|
784
|
+
export const RUNTIME_TASK_V2 = Object.freeze({
|
|
785
|
+
QUEUED: "queued",
|
|
786
|
+
RUNNING: "running",
|
|
787
|
+
COMPLETED: "completed",
|
|
788
|
+
FAILED: "failed",
|
|
789
|
+
CANCELED: "canceled",
|
|
790
|
+
});
|
|
791
|
+
|
|
792
|
+
const PLUGIN_TRANSITIONS_V2 = new Map([
|
|
793
|
+
["draft", new Set(["active", "retired"])],
|
|
794
|
+
["active", new Set(["deprecated", "retired"])],
|
|
795
|
+
["deprecated", new Set(["active", "retired"])],
|
|
796
|
+
]);
|
|
797
|
+
const PLUGIN_TERMINALS_V2 = new Set(["retired"]);
|
|
798
|
+
|
|
799
|
+
const RUNTIME_TASK_TRANSITIONS_V2 = new Map([
|
|
800
|
+
["queued", new Set(["running", "canceled", "failed"])],
|
|
801
|
+
["running", new Set(["completed", "failed", "canceled"])],
|
|
802
|
+
]);
|
|
803
|
+
const RUNTIME_TASK_TERMINALS_V2 = new Set(["completed", "failed", "canceled"]);
|
|
804
|
+
|
|
805
|
+
export const RT_DEFAULT_MAX_ACTIVE_PLUGINS_PER_OWNER = 40;
|
|
806
|
+
export const RT_DEFAULT_MAX_RUNNING_TASKS_PER_OWNER = 5;
|
|
807
|
+
export const RT_DEFAULT_PLUGIN_IDLE_MS = 90 * 86400000; // 90d
|
|
808
|
+
export const RT_DEFAULT_TASK_STUCK_MS = 4 * 3600000; // 4h
|
|
809
|
+
|
|
810
|
+
let _maxActivePluginsPerOwnerV2 = RT_DEFAULT_MAX_ACTIVE_PLUGINS_PER_OWNER;
|
|
811
|
+
let _maxRunningTasksPerOwnerV2 = RT_DEFAULT_MAX_RUNNING_TASKS_PER_OWNER;
|
|
812
|
+
let _pluginIdleMsV2 = RT_DEFAULT_PLUGIN_IDLE_MS;
|
|
813
|
+
let _taskStuckMsV2 = RT_DEFAULT_TASK_STUCK_MS;
|
|
814
|
+
|
|
815
|
+
function _positiveIntV2(n, label) {
|
|
816
|
+
const v = Math.floor(Number(n));
|
|
817
|
+
if (!Number.isFinite(v) || v <= 0)
|
|
818
|
+
throw new Error(`${label} must be a positive integer`);
|
|
819
|
+
return v;
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
export function getDefaultMaxActivePluginsPerOwnerV2() {
|
|
823
|
+
return RT_DEFAULT_MAX_ACTIVE_PLUGINS_PER_OWNER;
|
|
824
|
+
}
|
|
825
|
+
export function getMaxActivePluginsPerOwnerV2() {
|
|
826
|
+
return _maxActivePluginsPerOwnerV2;
|
|
827
|
+
}
|
|
828
|
+
export function setMaxActivePluginsPerOwnerV2(n) {
|
|
829
|
+
return (_maxActivePluginsPerOwnerV2 = _positiveIntV2(
|
|
830
|
+
n,
|
|
831
|
+
"maxActivePluginsPerOwner",
|
|
832
|
+
));
|
|
833
|
+
}
|
|
834
|
+
export function getDefaultMaxRunningTasksPerOwnerV2() {
|
|
835
|
+
return RT_DEFAULT_MAX_RUNNING_TASKS_PER_OWNER;
|
|
836
|
+
}
|
|
837
|
+
export function getMaxRunningTasksPerOwnerV2() {
|
|
838
|
+
return _maxRunningTasksPerOwnerV2;
|
|
839
|
+
}
|
|
840
|
+
export function setMaxRunningTasksPerOwnerV2(n) {
|
|
841
|
+
return (_maxRunningTasksPerOwnerV2 = _positiveIntV2(
|
|
842
|
+
n,
|
|
843
|
+
"maxRunningTasksPerOwner",
|
|
844
|
+
));
|
|
845
|
+
}
|
|
846
|
+
export function getDefaultPluginIdleMsV2() {
|
|
847
|
+
return RT_DEFAULT_PLUGIN_IDLE_MS;
|
|
848
|
+
}
|
|
849
|
+
export function getPluginIdleMsV2() {
|
|
850
|
+
return _pluginIdleMsV2;
|
|
851
|
+
}
|
|
852
|
+
export function setPluginIdleMsV2(ms) {
|
|
853
|
+
return (_pluginIdleMsV2 = _positiveIntV2(ms, "pluginIdleMs"));
|
|
854
|
+
}
|
|
855
|
+
export function getDefaultTaskStuckMsV2() {
|
|
856
|
+
return RT_DEFAULT_TASK_STUCK_MS;
|
|
857
|
+
}
|
|
858
|
+
export function getTaskStuckMsV2() {
|
|
859
|
+
return _taskStuckMsV2;
|
|
860
|
+
}
|
|
861
|
+
export function setTaskStuckMsV2(ms) {
|
|
862
|
+
return (_taskStuckMsV2 = _positiveIntV2(ms, "taskStuckMs"));
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
const _pluginsV2 = new Map();
|
|
866
|
+
const _runtimeTasksV2 = new Map();
|
|
867
|
+
|
|
868
|
+
export function registerPluginV2(
|
|
869
|
+
_db,
|
|
870
|
+
{ pluginId, ownerId, name, version, initialStatus, metadata } = {},
|
|
871
|
+
) {
|
|
872
|
+
if (!pluginId) throw new Error("pluginId is required");
|
|
873
|
+
if (!ownerId) throw new Error("ownerId is required");
|
|
874
|
+
if (_pluginsV2.has(pluginId))
|
|
875
|
+
throw new Error(`Plugin ${pluginId} already exists`);
|
|
876
|
+
const status = initialStatus || PLUGIN_MATURITY_V2.DRAFT;
|
|
877
|
+
if (!Object.values(PLUGIN_MATURITY_V2).includes(status))
|
|
878
|
+
throw new Error(`Invalid initial status: ${status}`);
|
|
879
|
+
if (PLUGIN_TERMINALS_V2.has(status))
|
|
880
|
+
throw new Error(`Cannot register in terminal status: ${status}`);
|
|
881
|
+
if (status === PLUGIN_MATURITY_V2.ACTIVE) {
|
|
882
|
+
if (getActivePluginCount(ownerId) >= _maxActivePluginsPerOwnerV2)
|
|
883
|
+
throw new Error(
|
|
884
|
+
`Owner ${ownerId} reached active-plugin cap (${_maxActivePluginsPerOwnerV2})`,
|
|
885
|
+
);
|
|
886
|
+
}
|
|
887
|
+
const now = Date.now();
|
|
888
|
+
const record = {
|
|
889
|
+
pluginId,
|
|
890
|
+
ownerId,
|
|
891
|
+
name: name || "",
|
|
892
|
+
version: version || "0.0.0",
|
|
893
|
+
status,
|
|
894
|
+
metadata: metadata || {},
|
|
895
|
+
createdAt: now,
|
|
896
|
+
updatedAt: now,
|
|
897
|
+
lastInvokedAt: now,
|
|
898
|
+
};
|
|
899
|
+
_pluginsV2.set(pluginId, record);
|
|
900
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
export function getPluginV2(pluginId) {
|
|
904
|
+
const r = _pluginsV2.get(pluginId);
|
|
905
|
+
return r ? { ...r, metadata: { ...r.metadata } } : null;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
export function setPluginMaturityV2(_db, pluginId, newStatus, patch = {}) {
|
|
909
|
+
const record = _pluginsV2.get(pluginId);
|
|
910
|
+
if (!record) throw new Error(`Unknown plugin: ${pluginId}`);
|
|
911
|
+
if (!Object.values(PLUGIN_MATURITY_V2).includes(newStatus))
|
|
912
|
+
throw new Error(`Invalid status: ${newStatus}`);
|
|
913
|
+
const allowed = PLUGIN_TRANSITIONS_V2.get(record.status) || new Set();
|
|
914
|
+
if (!allowed.has(newStatus))
|
|
915
|
+
throw new Error(`Invalid transition: ${record.status} -> ${newStatus}`);
|
|
916
|
+
if (newStatus === PLUGIN_MATURITY_V2.ACTIVE) {
|
|
917
|
+
if (getActivePluginCount(record.ownerId) >= _maxActivePluginsPerOwnerV2)
|
|
918
|
+
throw new Error(
|
|
919
|
+
`Owner ${record.ownerId} reached active-plugin cap (${_maxActivePluginsPerOwnerV2})`,
|
|
920
|
+
);
|
|
921
|
+
}
|
|
922
|
+
record.status = newStatus;
|
|
923
|
+
record.updatedAt = Date.now();
|
|
924
|
+
if (patch.reason !== undefined) record.lastReason = patch.reason;
|
|
925
|
+
if (patch.metadata)
|
|
926
|
+
record.metadata = { ...record.metadata, ...patch.metadata };
|
|
927
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
export function activatePluginV2(db, id, reason) {
|
|
931
|
+
return setPluginMaturityV2(db, id, PLUGIN_MATURITY_V2.ACTIVE, { reason });
|
|
932
|
+
}
|
|
933
|
+
export function deprecatePluginV2(db, id, reason) {
|
|
934
|
+
return setPluginMaturityV2(db, id, PLUGIN_MATURITY_V2.DEPRECATED, { reason });
|
|
935
|
+
}
|
|
936
|
+
export function retirePluginV2(db, id, reason) {
|
|
937
|
+
return setPluginMaturityV2(db, id, PLUGIN_MATURITY_V2.RETIRED, { reason });
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
export function touchPluginInvocation(pluginId) {
|
|
941
|
+
const record = _pluginsV2.get(pluginId);
|
|
942
|
+
if (!record) throw new Error(`Unknown plugin: ${pluginId}`);
|
|
943
|
+
record.lastInvokedAt = Date.now();
|
|
944
|
+
record.updatedAt = record.lastInvokedAt;
|
|
945
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
export function enqueueRuntimeTaskV2(
|
|
949
|
+
_db,
|
|
950
|
+
{ taskId, ownerId, pluginId, kind, metadata } = {},
|
|
951
|
+
) {
|
|
952
|
+
if (!taskId) throw new Error("taskId is required");
|
|
953
|
+
if (!ownerId) throw new Error("ownerId is required");
|
|
954
|
+
if (!pluginId) throw new Error("pluginId is required");
|
|
955
|
+
if (!kind) throw new Error("kind is required");
|
|
956
|
+
if (_runtimeTasksV2.has(taskId))
|
|
957
|
+
throw new Error(`Task ${taskId} already exists`);
|
|
958
|
+
const now = Date.now();
|
|
959
|
+
const record = {
|
|
960
|
+
taskId,
|
|
961
|
+
ownerId,
|
|
962
|
+
pluginId,
|
|
963
|
+
kind,
|
|
964
|
+
status: RUNTIME_TASK_V2.QUEUED,
|
|
965
|
+
metadata: metadata || {},
|
|
966
|
+
createdAt: now,
|
|
967
|
+
updatedAt: now,
|
|
968
|
+
};
|
|
969
|
+
_runtimeTasksV2.set(taskId, record);
|
|
970
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
export function getRuntimeTaskV2(taskId) {
|
|
974
|
+
const r = _runtimeTasksV2.get(taskId);
|
|
975
|
+
return r ? { ...r, metadata: { ...r.metadata } } : null;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
export function setRuntimeTaskStatusV2(_db, taskId, newStatus, patch = {}) {
|
|
979
|
+
const record = _runtimeTasksV2.get(taskId);
|
|
980
|
+
if (!record) throw new Error(`Unknown task: ${taskId}`);
|
|
981
|
+
if (!Object.values(RUNTIME_TASK_V2).includes(newStatus))
|
|
982
|
+
throw new Error(`Invalid status: ${newStatus}`);
|
|
983
|
+
const allowed = RUNTIME_TASK_TRANSITIONS_V2.get(record.status) || new Set();
|
|
984
|
+
if (!allowed.has(newStatus))
|
|
985
|
+
throw new Error(`Invalid transition: ${record.status} -> ${newStatus}`);
|
|
986
|
+
if (newStatus === RUNTIME_TASK_V2.RUNNING) {
|
|
987
|
+
if (getRunningTaskCount(record.ownerId) >= _maxRunningTasksPerOwnerV2)
|
|
988
|
+
throw new Error(
|
|
989
|
+
`Owner ${record.ownerId} reached running-task cap (${_maxRunningTasksPerOwnerV2})`,
|
|
990
|
+
);
|
|
991
|
+
record.startedAt = Date.now();
|
|
992
|
+
}
|
|
993
|
+
record.status = newStatus;
|
|
994
|
+
record.updatedAt = Date.now();
|
|
995
|
+
if (patch.reason !== undefined) record.lastReason = patch.reason;
|
|
996
|
+
if (patch.metadata)
|
|
997
|
+
record.metadata = { ...record.metadata, ...patch.metadata };
|
|
998
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
export function startRuntimeTask(db, id, reason) {
|
|
1002
|
+
return setRuntimeTaskStatusV2(db, id, RUNTIME_TASK_V2.RUNNING, { reason });
|
|
1003
|
+
}
|
|
1004
|
+
export function completeRuntimeTask(db, id, reason) {
|
|
1005
|
+
return setRuntimeTaskStatusV2(db, id, RUNTIME_TASK_V2.COMPLETED, { reason });
|
|
1006
|
+
}
|
|
1007
|
+
export function failRuntimeTask(db, id, reason) {
|
|
1008
|
+
return setRuntimeTaskStatusV2(db, id, RUNTIME_TASK_V2.FAILED, { reason });
|
|
1009
|
+
}
|
|
1010
|
+
export function cancelRuntimeTask(db, id, reason) {
|
|
1011
|
+
return setRuntimeTaskStatusV2(db, id, RUNTIME_TASK_V2.CANCELED, { reason });
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
export function getActivePluginCount(ownerId) {
|
|
1015
|
+
let n = 0;
|
|
1016
|
+
for (const r of _pluginsV2.values()) {
|
|
1017
|
+
if (r.status !== PLUGIN_MATURITY_V2.ACTIVE) continue;
|
|
1018
|
+
if (ownerId && r.ownerId !== ownerId) continue;
|
|
1019
|
+
n++;
|
|
1020
|
+
}
|
|
1021
|
+
return n;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
export function getRunningTaskCount(ownerId) {
|
|
1025
|
+
let n = 0;
|
|
1026
|
+
for (const r of _runtimeTasksV2.values()) {
|
|
1027
|
+
if (r.status !== RUNTIME_TASK_V2.RUNNING) continue;
|
|
1028
|
+
if (ownerId && r.ownerId !== ownerId) continue;
|
|
1029
|
+
n++;
|
|
1030
|
+
}
|
|
1031
|
+
return n;
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
export function autoRetireIdlePlugins(_db, nowMs) {
|
|
1035
|
+
const now = nowMs ?? Date.now();
|
|
1036
|
+
const flipped = [];
|
|
1037
|
+
for (const r of _pluginsV2.values()) {
|
|
1038
|
+
if (
|
|
1039
|
+
r.status === PLUGIN_MATURITY_V2.ACTIVE ||
|
|
1040
|
+
r.status === PLUGIN_MATURITY_V2.DEPRECATED
|
|
1041
|
+
) {
|
|
1042
|
+
if (now - r.lastInvokedAt > _pluginIdleMsV2) {
|
|
1043
|
+
r.status = PLUGIN_MATURITY_V2.RETIRED;
|
|
1044
|
+
r.updatedAt = now;
|
|
1045
|
+
r.lastReason = "idle";
|
|
1046
|
+
flipped.push(r.pluginId);
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
return { flipped, count: flipped.length };
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
export function autoFailStuckRuntimeTasks(_db, nowMs) {
|
|
1054
|
+
const now = nowMs ?? Date.now();
|
|
1055
|
+
const flipped = [];
|
|
1056
|
+
for (const r of _runtimeTasksV2.values()) {
|
|
1057
|
+
if (r.status === RUNTIME_TASK_V2.RUNNING) {
|
|
1058
|
+
const anchor = r.startedAt || r.createdAt;
|
|
1059
|
+
if (now - anchor > _taskStuckMsV2) {
|
|
1060
|
+
r.status = RUNTIME_TASK_V2.FAILED;
|
|
1061
|
+
r.updatedAt = now;
|
|
1062
|
+
r.lastReason = "stuck_timeout";
|
|
1063
|
+
flipped.push(r.taskId);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
return { flipped, count: flipped.length };
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
export function getRuntimeStatsV2() {
|
|
1071
|
+
const pluginsByStatus = {};
|
|
1072
|
+
for (const s of Object.values(PLUGIN_MATURITY_V2)) pluginsByStatus[s] = 0;
|
|
1073
|
+
const tasksByStatus = {};
|
|
1074
|
+
for (const s of Object.values(RUNTIME_TASK_V2)) tasksByStatus[s] = 0;
|
|
1075
|
+
for (const r of _pluginsV2.values()) pluginsByStatus[r.status]++;
|
|
1076
|
+
for (const r of _runtimeTasksV2.values()) tasksByStatus[r.status]++;
|
|
1077
|
+
return {
|
|
1078
|
+
totalPluginsV2: _pluginsV2.size,
|
|
1079
|
+
totalTasksV2: _runtimeTasksV2.size,
|
|
1080
|
+
maxActivePluginsPerOwner: _maxActivePluginsPerOwnerV2,
|
|
1081
|
+
maxRunningTasksPerOwner: _maxRunningTasksPerOwnerV2,
|
|
1082
|
+
pluginIdleMs: _pluginIdleMsV2,
|
|
1083
|
+
taskStuckMs: _taskStuckMsV2,
|
|
1084
|
+
pluginsByStatus,
|
|
1085
|
+
tasksByStatus,
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
export function _resetStateV2() {
|
|
1090
|
+
_maxActivePluginsPerOwnerV2 = RT_DEFAULT_MAX_ACTIVE_PLUGINS_PER_OWNER;
|
|
1091
|
+
_maxRunningTasksPerOwnerV2 = RT_DEFAULT_MAX_RUNNING_TASKS_PER_OWNER;
|
|
1092
|
+
_pluginIdleMsV2 = RT_DEFAULT_PLUGIN_IDLE_MS;
|
|
1093
|
+
_taskStuckMsV2 = RT_DEFAULT_TASK_STUCK_MS;
|
|
1094
|
+
_pluginsV2.clear();
|
|
1095
|
+
_runtimeTasksV2.clear();
|
|
1096
|
+
}
|
package/src/lib/user-profile.js
CHANGED
|
@@ -170,3 +170,84 @@ export async function consolidateUserProfile(llmFn) {
|
|
|
170
170
|
// ─── Exports ────────────────────────────────────────────────────────────────
|
|
171
171
|
|
|
172
172
|
export const MAX_USER_PROFILE_LENGTH = MAX_PROFILE_LENGTH;
|
|
173
|
+
|
|
174
|
+
// ===== V2 Surface: User Profile governance overlay (CLI v0.141.0) =====
|
|
175
|
+
export const USER_PROFILE_MATURITY_V2 = Object.freeze({
|
|
176
|
+
PENDING: "pending", ACTIVE: "active", DORMANT: "dormant", ARCHIVED: "archived",
|
|
177
|
+
});
|
|
178
|
+
export const USER_PREF_LIFECYCLE_V2 = Object.freeze({
|
|
179
|
+
PROPOSED: "proposed", APPLIED: "applied", REJECTED: "rejected", SUPERSEDED: "superseded", CANCELLED: "cancelled",
|
|
180
|
+
});
|
|
181
|
+
const _upTrans = new Map([
|
|
182
|
+
[USER_PROFILE_MATURITY_V2.PENDING, new Set([USER_PROFILE_MATURITY_V2.ACTIVE, USER_PROFILE_MATURITY_V2.ARCHIVED])],
|
|
183
|
+
[USER_PROFILE_MATURITY_V2.ACTIVE, new Set([USER_PROFILE_MATURITY_V2.DORMANT, USER_PROFILE_MATURITY_V2.ARCHIVED])],
|
|
184
|
+
[USER_PROFILE_MATURITY_V2.DORMANT, new Set([USER_PROFILE_MATURITY_V2.ACTIVE, USER_PROFILE_MATURITY_V2.ARCHIVED])],
|
|
185
|
+
[USER_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
|
|
186
|
+
]);
|
|
187
|
+
const _upTerminal = new Set([USER_PROFILE_MATURITY_V2.ARCHIVED]);
|
|
188
|
+
const _uprefTrans = new Map([
|
|
189
|
+
[USER_PREF_LIFECYCLE_V2.PROPOSED, new Set([USER_PREF_LIFECYCLE_V2.APPLIED, USER_PREF_LIFECYCLE_V2.REJECTED, USER_PREF_LIFECYCLE_V2.CANCELLED])],
|
|
190
|
+
[USER_PREF_LIFECYCLE_V2.APPLIED, new Set([USER_PREF_LIFECYCLE_V2.SUPERSEDED])],
|
|
191
|
+
[USER_PREF_LIFECYCLE_V2.REJECTED, new Set()],
|
|
192
|
+
[USER_PREF_LIFECYCLE_V2.SUPERSEDED, new Set()],
|
|
193
|
+
[USER_PREF_LIFECYCLE_V2.CANCELLED, new Set()],
|
|
194
|
+
]);
|
|
195
|
+
const _upsV2 = new Map();
|
|
196
|
+
const _uprefsV2 = new Map();
|
|
197
|
+
let _upMaxActivePerOwner = 5, _upMaxPendingPrefsPerProfile = 20, _upIdleMs = 90 * 24 * 60 * 60 * 1000, _uprefStuckMs = 7 * 24 * 60 * 60 * 1000;
|
|
198
|
+
function _upPos(n, label) { const v = Math.floor(Number(n)); if (!Number.isFinite(v) || v <= 0) throw new Error(`${label} must be positive integer`); return v; }
|
|
199
|
+
function _upCheckP(from, to) { const a = _upTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid user profile transition ${from} → ${to}`); }
|
|
200
|
+
function _uprefCheck(from, to) { const a = _uprefTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid user pref transition ${from} → ${to}`); }
|
|
201
|
+
export function setMaxActiveUserProfilesPerOwnerV2(n) { _upMaxActivePerOwner = _upPos(n, "maxActiveUserProfilesPerOwner"); }
|
|
202
|
+
export function getMaxActiveUserProfilesPerOwnerV2() { return _upMaxActivePerOwner; }
|
|
203
|
+
export function setMaxPendingUserPrefsPerProfileV2(n) { _upMaxPendingPrefsPerProfile = _upPos(n, "maxPendingUserPrefsPerProfile"); }
|
|
204
|
+
export function getMaxPendingUserPrefsPerProfileV2() { return _upMaxPendingPrefsPerProfile; }
|
|
205
|
+
export function setUserProfileIdleMsV2(n) { _upIdleMs = _upPos(n, "userProfileIdleMs"); }
|
|
206
|
+
export function getUserProfileIdleMsV2() { return _upIdleMs; }
|
|
207
|
+
export function setUserPrefStuckMsV2(n) { _uprefStuckMs = _upPos(n, "userPrefStuckMs"); }
|
|
208
|
+
export function getUserPrefStuckMsV2() { return _uprefStuckMs; }
|
|
209
|
+
export function _resetStateUserProfileV2() { _upsV2.clear(); _uprefsV2.clear(); _upMaxActivePerOwner = 5; _upMaxPendingPrefsPerProfile = 20; _upIdleMs = 90 * 24 * 60 * 60 * 1000; _uprefStuckMs = 7 * 24 * 60 * 60 * 1000; }
|
|
210
|
+
export function registerUserProfileV2({ id, owner, handle, metadata } = {}) {
|
|
211
|
+
if (!id) throw new Error("user profile id required"); if (!owner) throw new Error("user profile owner required");
|
|
212
|
+
if (_upsV2.has(id)) throw new Error(`user profile ${id} already registered`);
|
|
213
|
+
const now = Date.now();
|
|
214
|
+
const p = { id, owner, handle: handle || id, status: USER_PROFILE_MATURITY_V2.PENDING, createdAt: now, updatedAt: now, activatedAt: null, archivedAt: null, lastTouchedAt: now, metadata: { ...(metadata || {}) } };
|
|
215
|
+
_upsV2.set(id, p); return { ...p, metadata: { ...p.metadata } };
|
|
216
|
+
}
|
|
217
|
+
function _upCountActive(owner) { let n = 0; for (const p of _upsV2.values()) if (p.owner === owner && p.status === USER_PROFILE_MATURITY_V2.ACTIVE) n++; return n; }
|
|
218
|
+
export function activateUserProfileV2(id) {
|
|
219
|
+
const p = _upsV2.get(id); if (!p) throw new Error(`user profile ${id} not found`);
|
|
220
|
+
_upCheckP(p.status, USER_PROFILE_MATURITY_V2.ACTIVE);
|
|
221
|
+
const recovery = p.status === USER_PROFILE_MATURITY_V2.DORMANT;
|
|
222
|
+
if (!recovery && _upCountActive(p.owner) >= _upMaxActivePerOwner) throw new Error(`max active user profiles for owner ${p.owner} reached`);
|
|
223
|
+
const now = Date.now(); p.status = USER_PROFILE_MATURITY_V2.ACTIVE; p.updatedAt = now; p.lastTouchedAt = now; if (!p.activatedAt) p.activatedAt = now;
|
|
224
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
225
|
+
}
|
|
226
|
+
export function dormantUserProfileV2(id) { const p = _upsV2.get(id); if (!p) throw new Error(`user profile ${id} not found`); _upCheckP(p.status, USER_PROFILE_MATURITY_V2.DORMANT); p.status = USER_PROFILE_MATURITY_V2.DORMANT; p.updatedAt = Date.now(); return { ...p, metadata: { ...p.metadata } }; }
|
|
227
|
+
export function archiveUserProfileV2(id) { const p = _upsV2.get(id); if (!p) throw new Error(`user profile ${id} not found`); _upCheckP(p.status, USER_PROFILE_MATURITY_V2.ARCHIVED); const now = Date.now(); p.status = USER_PROFILE_MATURITY_V2.ARCHIVED; p.updatedAt = now; if (!p.archivedAt) p.archivedAt = now; return { ...p, metadata: { ...p.metadata } }; }
|
|
228
|
+
export function touchUserProfileV2(id) { const p = _upsV2.get(id); if (!p) throw new Error(`user profile ${id} not found`); if (_upTerminal.has(p.status)) throw new Error(`cannot touch terminal user profile ${id}`); const now = Date.now(); p.lastTouchedAt = now; p.updatedAt = now; return { ...p, metadata: { ...p.metadata } }; }
|
|
229
|
+
export function getUserProfileV2(id) { const p = _upsV2.get(id); if (!p) return null; return { ...p, metadata: { ...p.metadata } }; }
|
|
230
|
+
export function listUserProfilesV2() { return [..._upsV2.values()].map((p) => ({ ...p, metadata: { ...p.metadata } })); }
|
|
231
|
+
function _uprefCountPending(profileId) { let n = 0; for (const r of _uprefsV2.values()) if (r.profileId === profileId && r.status === USER_PREF_LIFECYCLE_V2.PROPOSED) n++; return n; }
|
|
232
|
+
export function createUserPrefV2({ id, profileId, key, metadata } = {}) {
|
|
233
|
+
if (!id) throw new Error("user pref id required"); if (!profileId) throw new Error("user pref profileId required");
|
|
234
|
+
if (_uprefsV2.has(id)) throw new Error(`user pref ${id} already exists`);
|
|
235
|
+
if (!_upsV2.has(profileId)) throw new Error(`user profile ${profileId} not found`);
|
|
236
|
+
if (_uprefCountPending(profileId) >= _upMaxPendingPrefsPerProfile) throw new Error(`max pending user prefs for profile ${profileId} reached`);
|
|
237
|
+
const now = Date.now();
|
|
238
|
+
const r = { id, profileId, key: key || "", status: USER_PREF_LIFECYCLE_V2.PROPOSED, createdAt: now, updatedAt: now, startedAt: now, settledAt: null, metadata: { ...(metadata || {}) } };
|
|
239
|
+
_uprefsV2.set(id, r); return { ...r, metadata: { ...r.metadata } };
|
|
240
|
+
}
|
|
241
|
+
export function applyUserPrefV2(id) { const r = _uprefsV2.get(id); if (!r) throw new Error(`user pref ${id} not found`); _uprefCheck(r.status, USER_PREF_LIFECYCLE_V2.APPLIED); const now = Date.now(); r.status = USER_PREF_LIFECYCLE_V2.APPLIED; r.updatedAt = now; if (!r.settledAt) r.settledAt = now; return { ...r, metadata: { ...r.metadata } }; }
|
|
242
|
+
export function rejectUserPrefV2(id, reason) { const r = _uprefsV2.get(id); if (!r) throw new Error(`user pref ${id} not found`); _uprefCheck(r.status, USER_PREF_LIFECYCLE_V2.REJECTED); const now = Date.now(); r.status = USER_PREF_LIFECYCLE_V2.REJECTED; r.updatedAt = now; if (!r.settledAt) r.settledAt = now; if (reason) r.metadata.rejectReason = String(reason); return { ...r, metadata: { ...r.metadata } }; }
|
|
243
|
+
export function supersedeUserPrefV2(id) { const r = _uprefsV2.get(id); if (!r) throw new Error(`user pref ${id} not found`); _uprefCheck(r.status, USER_PREF_LIFECYCLE_V2.SUPERSEDED); const now = Date.now(); r.status = USER_PREF_LIFECYCLE_V2.SUPERSEDED; r.updatedAt = now; if (!r.settledAt) r.settledAt = now; return { ...r, metadata: { ...r.metadata } }; }
|
|
244
|
+
export function cancelUserPrefV2(id, reason) { const r = _uprefsV2.get(id); if (!r) throw new Error(`user pref ${id} not found`); _uprefCheck(r.status, USER_PREF_LIFECYCLE_V2.CANCELLED); const now = Date.now(); r.status = USER_PREF_LIFECYCLE_V2.CANCELLED; r.updatedAt = now; if (!r.settledAt) r.settledAt = now; if (reason) r.metadata.cancelReason = String(reason); return { ...r, metadata: { ...r.metadata } }; }
|
|
245
|
+
export function getUserPrefV2(id) { const r = _uprefsV2.get(id); if (!r) return null; return { ...r, metadata: { ...r.metadata } }; }
|
|
246
|
+
export function listUserPrefsV2() { return [..._uprefsV2.values()].map((r) => ({ ...r, metadata: { ...r.metadata } })); }
|
|
247
|
+
export function autoDormantIdleUserProfilesV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const p of _upsV2.values()) if (p.status === USER_PROFILE_MATURITY_V2.ACTIVE && (t - p.lastTouchedAt) >= _upIdleMs) { p.status = USER_PROFILE_MATURITY_V2.DORMANT; p.updatedAt = t; flipped.push(p.id); } return { flipped, count: flipped.length }; }
|
|
248
|
+
export function autoCancelStaleUserPrefsV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const r of _uprefsV2.values()) if (r.status === USER_PREF_LIFECYCLE_V2.PROPOSED && (t - r.startedAt) >= _uprefStuckMs) { r.status = USER_PREF_LIFECYCLE_V2.CANCELLED; r.updatedAt = t; if (!r.settledAt) r.settledAt = t; r.metadata.cancelReason = "auto-cancel-stale"; flipped.push(r.id); } return { flipped, count: flipped.length }; }
|
|
249
|
+
export function getUserProfileGovStatsV2() {
|
|
250
|
+
const profilesByStatus = {}; for (const v of Object.values(USER_PROFILE_MATURITY_V2)) profilesByStatus[v] = 0; for (const p of _upsV2.values()) profilesByStatus[p.status]++;
|
|
251
|
+
const prefsByStatus = {}; for (const v of Object.values(USER_PREF_LIFECYCLE_V2)) prefsByStatus[v] = 0; for (const r of _uprefsV2.values()) prefsByStatus[r.status]++;
|
|
252
|
+
return { totalUserProfilesV2: _upsV2.size, totalUserPrefsV2: _uprefsV2.size, maxActiveUserProfilesPerOwner: _upMaxActivePerOwner, maxPendingUserPrefsPerProfile: _upMaxPendingPrefsPerProfile, userProfileIdleMs: _upIdleMs, userPrefStuckMs: _uprefStuckMs, profilesByStatus, prefsByStatus };
|
|
253
|
+
}
|
|
@@ -98,3 +98,84 @@ function filterByChannel(releases, channel) {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
export { fetchReleases, filterByChannel };
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
// =====================================================================
|
|
104
|
+
// Version Checker V2 governance overlay
|
|
105
|
+
// =====================================================================
|
|
106
|
+
export const VCHK_PROFILE_MATURITY_V2 = Object.freeze({ PENDING: "pending", ACTIVE: "active", STALE: "stale", ARCHIVED: "archived" });
|
|
107
|
+
export const VCHK_CHECK_LIFECYCLE_V2 = Object.freeze({ QUEUED: "queued", CHECKING: "checking", COMPLETED: "completed", FAILED: "failed", CANCELLED: "cancelled" });
|
|
108
|
+
const _vchkPTrans = new Map([
|
|
109
|
+
[VCHK_PROFILE_MATURITY_V2.PENDING, new Set([VCHK_PROFILE_MATURITY_V2.ACTIVE, VCHK_PROFILE_MATURITY_V2.ARCHIVED])],
|
|
110
|
+
[VCHK_PROFILE_MATURITY_V2.ACTIVE, new Set([VCHK_PROFILE_MATURITY_V2.STALE, VCHK_PROFILE_MATURITY_V2.ARCHIVED])],
|
|
111
|
+
[VCHK_PROFILE_MATURITY_V2.STALE, new Set([VCHK_PROFILE_MATURITY_V2.ACTIVE, VCHK_PROFILE_MATURITY_V2.ARCHIVED])],
|
|
112
|
+
[VCHK_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
|
|
113
|
+
]);
|
|
114
|
+
const _vchkPTerminal = new Set([VCHK_PROFILE_MATURITY_V2.ARCHIVED]);
|
|
115
|
+
const _vchkCTrans = new Map([
|
|
116
|
+
[VCHK_CHECK_LIFECYCLE_V2.QUEUED, new Set([VCHK_CHECK_LIFECYCLE_V2.CHECKING, VCHK_CHECK_LIFECYCLE_V2.CANCELLED])],
|
|
117
|
+
[VCHK_CHECK_LIFECYCLE_V2.CHECKING, new Set([VCHK_CHECK_LIFECYCLE_V2.COMPLETED, VCHK_CHECK_LIFECYCLE_V2.FAILED, VCHK_CHECK_LIFECYCLE_V2.CANCELLED])],
|
|
118
|
+
[VCHK_CHECK_LIFECYCLE_V2.COMPLETED, new Set()],
|
|
119
|
+
[VCHK_CHECK_LIFECYCLE_V2.FAILED, new Set()],
|
|
120
|
+
[VCHK_CHECK_LIFECYCLE_V2.CANCELLED, new Set()],
|
|
121
|
+
]);
|
|
122
|
+
const _vchkPsV2 = new Map();
|
|
123
|
+
const _vchkCsV2 = new Map();
|
|
124
|
+
let _vchkMaxActive = 5, _vchkMaxPending = 10, _vchkIdleMs = 30 * 24 * 60 * 60 * 1000, _vchkStuckMs = 30 * 1000;
|
|
125
|
+
function _vchkPos(n, label) { const v = Math.floor(Number(n)); if (!Number.isFinite(v) || v <= 0) throw new Error(`${label} must be positive integer`); return v; }
|
|
126
|
+
function _vchkCheckP(from, to) { const a = _vchkPTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid vchk profile transition ${from} → ${to}`); }
|
|
127
|
+
function _vchkCheckC(from, to) { const a = _vchkCTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid vchk check transition ${from} → ${to}`); }
|
|
128
|
+
function _vchkCountActive(owner) { let c = 0; for (const p of _vchkPsV2.values()) if (p.owner === owner && p.status === VCHK_PROFILE_MATURITY_V2.ACTIVE) c++; return c; }
|
|
129
|
+
function _vchkCountPending(profileId) { let c = 0; for (const x of _vchkCsV2.values()) if (x.profileId === profileId && (x.status === VCHK_CHECK_LIFECYCLE_V2.QUEUED || x.status === VCHK_CHECK_LIFECYCLE_V2.CHECKING)) c++; return c; }
|
|
130
|
+
export function setMaxActiveVchkProfilesPerOwnerV2(n) { _vchkMaxActive = _vchkPos(n, "maxActiveVchkProfilesPerOwner"); }
|
|
131
|
+
export function getMaxActiveVchkProfilesPerOwnerV2() { return _vchkMaxActive; }
|
|
132
|
+
export function setMaxPendingVchkChecksPerProfileV2(n) { _vchkMaxPending = _vchkPos(n, "maxPendingVchkChecksPerProfile"); }
|
|
133
|
+
export function getMaxPendingVchkChecksPerProfileV2() { return _vchkMaxPending; }
|
|
134
|
+
export function setVchkProfileIdleMsV2(n) { _vchkIdleMs = _vchkPos(n, "vchkProfileIdleMs"); }
|
|
135
|
+
export function getVchkProfileIdleMsV2() { return _vchkIdleMs; }
|
|
136
|
+
export function setVchkCheckStuckMsV2(n) { _vchkStuckMs = _vchkPos(n, "vchkCheckStuckMs"); }
|
|
137
|
+
export function getVchkCheckStuckMsV2() { return _vchkStuckMs; }
|
|
138
|
+
export function _resetStateVersionCheckerV2() { _vchkPsV2.clear(); _vchkCsV2.clear(); _vchkMaxActive = 5; _vchkMaxPending = 10; _vchkIdleMs = 30 * 24 * 60 * 60 * 1000; _vchkStuckMs = 30 * 1000; }
|
|
139
|
+
export function registerVchkProfileV2({ id, owner, channel, metadata } = {}) {
|
|
140
|
+
if (!id || !owner) throw new Error("id and owner required");
|
|
141
|
+
if (_vchkPsV2.has(id)) throw new Error(`vchk profile ${id} already exists`);
|
|
142
|
+
const now = Date.now();
|
|
143
|
+
const p = { id, owner, channel: channel || "stable", status: VCHK_PROFILE_MATURITY_V2.PENDING, createdAt: now, updatedAt: now, lastTouchedAt: now, activatedAt: null, archivedAt: null, metadata: { ...(metadata || {}) } };
|
|
144
|
+
_vchkPsV2.set(id, p); return { ...p, metadata: { ...p.metadata } };
|
|
145
|
+
}
|
|
146
|
+
export function activateVchkProfileV2(id) {
|
|
147
|
+
const p = _vchkPsV2.get(id); if (!p) throw new Error(`vchk profile ${id} not found`);
|
|
148
|
+
const isInitial = p.status === VCHK_PROFILE_MATURITY_V2.PENDING;
|
|
149
|
+
_vchkCheckP(p.status, VCHK_PROFILE_MATURITY_V2.ACTIVE);
|
|
150
|
+
if (isInitial && _vchkCountActive(p.owner) >= _vchkMaxActive) throw new Error(`max active vchk profiles for owner ${p.owner} reached`);
|
|
151
|
+
const now = Date.now(); p.status = VCHK_PROFILE_MATURITY_V2.ACTIVE; p.updatedAt = now; p.lastTouchedAt = now;
|
|
152
|
+
if (!p.activatedAt) p.activatedAt = now;
|
|
153
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
154
|
+
}
|
|
155
|
+
export function staleVchkProfileV2(id) { const p = _vchkPsV2.get(id); if (!p) throw new Error(`vchk profile ${id} not found`); _vchkCheckP(p.status, VCHK_PROFILE_MATURITY_V2.STALE); p.status = VCHK_PROFILE_MATURITY_V2.STALE; p.updatedAt = Date.now(); return { ...p, metadata: { ...p.metadata } }; }
|
|
156
|
+
export function archiveVchkProfileV2(id) { const p = _vchkPsV2.get(id); if (!p) throw new Error(`vchk profile ${id} not found`); _vchkCheckP(p.status, VCHK_PROFILE_MATURITY_V2.ARCHIVED); const now = Date.now(); p.status = VCHK_PROFILE_MATURITY_V2.ARCHIVED; p.updatedAt = now; if (!p.archivedAt) p.archivedAt = now; return { ...p, metadata: { ...p.metadata } }; }
|
|
157
|
+
export function touchVchkProfileV2(id) { const p = _vchkPsV2.get(id); if (!p) throw new Error(`vchk profile ${id} not found`); if (_vchkPTerminal.has(p.status)) throw new Error(`cannot touch terminal vchk profile ${id}`); const now = Date.now(); p.lastTouchedAt = now; p.updatedAt = now; return { ...p, metadata: { ...p.metadata } }; }
|
|
158
|
+
export function getVchkProfileV2(id) { const p = _vchkPsV2.get(id); if (!p) return null; return { ...p, metadata: { ...p.metadata } }; }
|
|
159
|
+
export function listVchkProfilesV2() { return [..._vchkPsV2.values()].map((p) => ({ ...p, metadata: { ...p.metadata } })); }
|
|
160
|
+
export function createVchkCheckV2({ id, profileId, currentVersion, metadata } = {}) {
|
|
161
|
+
if (!id || !profileId) throw new Error("id and profileId required");
|
|
162
|
+
if (_vchkCsV2.has(id)) throw new Error(`vchk check ${id} already exists`);
|
|
163
|
+
if (!_vchkPsV2.has(profileId)) throw new Error(`vchk profile ${profileId} not found`);
|
|
164
|
+
if (_vchkCountPending(profileId) >= _vchkMaxPending) throw new Error(`max pending vchk checks for profile ${profileId} reached`);
|
|
165
|
+
const now = Date.now();
|
|
166
|
+
const c = { id, profileId, currentVersion: currentVersion || "", status: VCHK_CHECK_LIFECYCLE_V2.QUEUED, createdAt: now, updatedAt: now, startedAt: null, settledAt: null, metadata: { ...(metadata || {}) } };
|
|
167
|
+
_vchkCsV2.set(id, c); return { ...c, metadata: { ...c.metadata } };
|
|
168
|
+
}
|
|
169
|
+
export function checkingVchkCheckV2(id) { const c = _vchkCsV2.get(id); if (!c) throw new Error(`vchk check ${id} not found`); _vchkCheckC(c.status, VCHK_CHECK_LIFECYCLE_V2.CHECKING); const now = Date.now(); c.status = VCHK_CHECK_LIFECYCLE_V2.CHECKING; c.updatedAt = now; if (!c.startedAt) c.startedAt = now; return { ...c, metadata: { ...c.metadata } }; }
|
|
170
|
+
export function completeVchkCheckV2(id) { const c = _vchkCsV2.get(id); if (!c) throw new Error(`vchk check ${id} not found`); _vchkCheckC(c.status, VCHK_CHECK_LIFECYCLE_V2.COMPLETED); const now = Date.now(); c.status = VCHK_CHECK_LIFECYCLE_V2.COMPLETED; c.updatedAt = now; if (!c.settledAt) c.settledAt = now; return { ...c, metadata: { ...c.metadata } }; }
|
|
171
|
+
export function failVchkCheckV2(id, reason) { const c = _vchkCsV2.get(id); if (!c) throw new Error(`vchk check ${id} not found`); _vchkCheckC(c.status, VCHK_CHECK_LIFECYCLE_V2.FAILED); const now = Date.now(); c.status = VCHK_CHECK_LIFECYCLE_V2.FAILED; c.updatedAt = now; if (!c.settledAt) c.settledAt = now; if (reason) c.metadata.failReason = String(reason); return { ...c, metadata: { ...c.metadata } }; }
|
|
172
|
+
export function cancelVchkCheckV2(id, reason) { const c = _vchkCsV2.get(id); if (!c) throw new Error(`vchk check ${id} not found`); _vchkCheckC(c.status, VCHK_CHECK_LIFECYCLE_V2.CANCELLED); const now = Date.now(); c.status = VCHK_CHECK_LIFECYCLE_V2.CANCELLED; c.updatedAt = now; if (!c.settledAt) c.settledAt = now; if (reason) c.metadata.cancelReason = String(reason); return { ...c, metadata: { ...c.metadata } }; }
|
|
173
|
+
export function getVchkCheckV2(id) { const c = _vchkCsV2.get(id); if (!c) return null; return { ...c, metadata: { ...c.metadata } }; }
|
|
174
|
+
export function listVchkChecksV2() { return [..._vchkCsV2.values()].map((c) => ({ ...c, metadata: { ...c.metadata } })); }
|
|
175
|
+
export function autoStaleIdleVchkProfilesV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const p of _vchkPsV2.values()) if (p.status === VCHK_PROFILE_MATURITY_V2.ACTIVE && (t - p.lastTouchedAt) >= _vchkIdleMs) { p.status = VCHK_PROFILE_MATURITY_V2.STALE; p.updatedAt = t; flipped.push(p.id); } return { flipped, count: flipped.length }; }
|
|
176
|
+
export function autoFailStuckVchkChecksV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const c of _vchkCsV2.values()) if (c.status === VCHK_CHECK_LIFECYCLE_V2.CHECKING && c.startedAt != null && (t - c.startedAt) >= _vchkStuckMs) { c.status = VCHK_CHECK_LIFECYCLE_V2.FAILED; c.updatedAt = t; if (!c.settledAt) c.settledAt = t; c.metadata.failReason = "auto-fail-stuck"; flipped.push(c.id); } return { flipped, count: flipped.length }; }
|
|
177
|
+
export function getVersionCheckerGovStatsV2() {
|
|
178
|
+
const profilesByStatus = {}; for (const v of Object.values(VCHK_PROFILE_MATURITY_V2)) profilesByStatus[v] = 0; for (const p of _vchkPsV2.values()) profilesByStatus[p.status]++;
|
|
179
|
+
const checksByStatus = {}; for (const v of Object.values(VCHK_CHECK_LIFECYCLE_V2)) checksByStatus[v] = 0; for (const c of _vchkCsV2.values()) checksByStatus[c.status]++;
|
|
180
|
+
return { totalVchkProfilesV2: _vchkPsV2.size, totalVchkChecksV2: _vchkCsV2.size, maxActiveVchkProfilesPerOwner: _vchkMaxActive, maxPendingVchkChecksPerProfile: _vchkMaxPending, vchkProfileIdleMs: _vchkIdleMs, vchkCheckStuckMs: _vchkStuckMs, profilesByStatus, checksByStatus };
|
|
181
|
+
}
|