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.
Files changed (209) hide show
  1. package/bin/chainlesschain.js +0 -0
  2. package/package.json +1 -1
  3. package/src/commands/a2a.js +62 -0
  4. package/src/commands/activitypub.js +61 -0
  5. package/src/commands/agent-network.js +254 -1
  6. package/src/commands/agent.js +117 -0
  7. package/src/commands/audit.js +302 -0
  8. package/src/commands/automation.js +271 -1
  9. package/src/commands/bi.js +61 -0
  10. package/src/commands/bm25.js +78 -0
  11. package/src/commands/browse.js +64 -0
  12. package/src/commands/ccron.js +78 -0
  13. package/src/commands/codegen.js +224 -0
  14. package/src/commands/collab.js +341 -0
  15. package/src/commands/compliance.js +1075 -0
  16. package/src/commands/compt.js +78 -0
  17. package/src/commands/consol.js +231 -0
  18. package/src/commands/cowork.js +263 -0
  19. package/src/commands/crosschain.js +62 -0
  20. package/src/commands/dao.js +62 -0
  21. package/src/commands/dbevo.js +284 -0
  22. package/src/commands/dev.js +252 -0
  23. package/src/commands/did.js +358 -0
  24. package/src/commands/dlp.js +61 -0
  25. package/src/commands/economy.js +56 -0
  26. package/src/commands/encrypt.js +341 -0
  27. package/src/commands/evolution.js +56 -0
  28. package/src/commands/evomap.js +61 -0
  29. package/src/commands/export.js +256 -1
  30. package/src/commands/fflag.js +178 -0
  31. package/src/commands/fusion.js +258 -0
  32. package/src/commands/git.js +45 -0
  33. package/src/commands/governance.js +325 -0
  34. package/src/commands/hardening.js +411 -0
  35. package/src/commands/hmemory.js +56 -0
  36. package/src/commands/hook.js +148 -0
  37. package/src/commands/import.js +252 -0
  38. package/src/commands/incentive.js +322 -0
  39. package/src/commands/inference.js +42 -0
  40. package/src/commands/infra.js +244 -0
  41. package/src/commands/instinct.js +260 -0
  42. package/src/commands/ipfs.js +318 -0
  43. package/src/commands/itbudget.js +45 -0
  44. package/src/commands/kg.js +387 -0
  45. package/src/commands/llm.js +263 -0
  46. package/src/commands/lowcode.js +44 -0
  47. package/src/commands/matrix.js +62 -0
  48. package/src/commands/mcp.js +221 -0
  49. package/src/commands/mcpscaf.js +41 -0
  50. package/src/commands/meminj.js +41 -0
  51. package/src/commands/memory.js +248 -0
  52. package/src/commands/multimodal.js +296 -0
  53. package/src/commands/nlprog.js +356 -0
  54. package/src/commands/nostr.js +62 -0
  55. package/src/commands/note.js +244 -0
  56. package/src/commands/ops.js +354 -0
  57. package/src/commands/orchestrate.js +166 -0
  58. package/src/commands/orchgov.js +45 -0
  59. package/src/commands/org.js +277 -0
  60. package/src/commands/p2p.js +390 -0
  61. package/src/commands/pdfp.js +78 -0
  62. package/src/commands/perception.js +290 -0
  63. package/src/commands/perf.js +39 -0
  64. package/src/commands/perm.js +45 -0
  65. package/src/commands/permmem.js +251 -0
  66. package/src/commands/pipeline.js +57 -1
  67. package/src/commands/planmode.js +45 -0
  68. package/src/commands/plugin-ecosystem.js +273 -0
  69. package/src/commands/pqc.js +393 -0
  70. package/src/commands/promcomp.js +82 -0
  71. package/src/commands/quantization.js +351 -0
  72. package/src/commands/rcache.js +271 -0
  73. package/src/commands/recommend.js +382 -0
  74. package/src/commands/runtime.js +307 -0
  75. package/src/commands/scim.js +262 -0
  76. package/src/commands/seshhook.js +41 -0
  77. package/src/commands/seshsearch.js +41 -0
  78. package/src/commands/seshtail.js +41 -0
  79. package/src/commands/seshu.js +41 -0
  80. package/src/commands/session.js +258 -0
  81. package/src/commands/sganal.js +78 -0
  82. package/src/commands/siem.js +40 -0
  83. package/src/commands/skill.js +267 -1
  84. package/src/commands/slotfill.js +41 -0
  85. package/src/commands/social.js +290 -0
  86. package/src/commands/sso.js +186 -1
  87. package/src/commands/svccont.js +45 -0
  88. package/src/commands/sync.js +256 -0
  89. package/src/commands/tech.js +338 -0
  90. package/src/commands/tenant.js +351 -0
  91. package/src/commands/tms.js +45 -0
  92. package/src/commands/tokens.js +269 -0
  93. package/src/commands/topiccls.js +45 -0
  94. package/src/commands/trust.js +249 -0
  95. package/src/commands/uprof.js +45 -0
  96. package/src/commands/vcheck.js +78 -0
  97. package/src/commands/wallet.js +277 -0
  98. package/src/commands/webfetch.js +41 -0
  99. package/src/commands/workflow.js +171 -0
  100. package/src/commands/zkp.js +62 -0
  101. package/src/harness/prompt-compressor.js +331 -0
  102. package/src/index.js +65 -1
  103. package/src/lib/a2a-protocol.js +105 -0
  104. package/src/lib/activitypub-bridge.js +105 -0
  105. package/src/lib/agent-coordinator.js +325 -0
  106. package/src/lib/agent-economy.js +105 -0
  107. package/src/lib/agent-network.js +387 -0
  108. package/src/lib/agent-router.js +395 -0
  109. package/src/lib/aiops.js +478 -0
  110. package/src/lib/app-builder.js +105 -0
  111. package/src/lib/audit-logger.js +379 -0
  112. package/src/lib/automation-engine.js +330 -0
  113. package/src/lib/autonomous-agent.js +105 -0
  114. package/src/lib/autonomous-developer.js +350 -0
  115. package/src/lib/bi-engine.js +105 -0
  116. package/src/lib/bm25-search.js +81 -0
  117. package/src/lib/browser-automation.js +105 -0
  118. package/src/lib/code-agent.js +323 -0
  119. package/src/lib/collaboration-governance.js +364 -0
  120. package/src/lib/community-governance.js +436 -0
  121. package/src/lib/compliance-framework-reporter.js +105 -0
  122. package/src/lib/compliance-manager.js +434 -0
  123. package/src/lib/compression-telemetry.js +81 -0
  124. package/src/lib/content-recommendation.js +469 -0
  125. package/src/lib/content-recommender.js +105 -0
  126. package/src/lib/cowork-cron.js +81 -0
  127. package/src/lib/cowork-task-runner.js +105 -0
  128. package/src/lib/cross-chain.js +105 -0
  129. package/src/lib/crypto-manager.js +350 -0
  130. package/src/lib/dao-governance.js +105 -0
  131. package/src/lib/dbevo.js +338 -0
  132. package/src/lib/decentral-infra.js +340 -0
  133. package/src/lib/did-manager.js +367 -0
  134. package/src/lib/dlp-engine.js +105 -0
  135. package/src/lib/evolution-system.js +105 -0
  136. package/src/lib/evomap-manager.js +105 -0
  137. package/src/lib/execution-backend.js +105 -0
  138. package/src/lib/feature-flags.js +85 -0
  139. package/src/lib/git-integration.js +105 -0
  140. package/src/lib/hardening-manager.js +348 -0
  141. package/src/lib/hierarchical-memory.js +105 -0
  142. package/src/lib/hook-manager.js +380 -0
  143. package/src/lib/inference-network.js +105 -0
  144. package/src/lib/instinct-manager.js +332 -0
  145. package/src/lib/ipfs-storage.js +334 -0
  146. package/src/lib/iteration-budget.js +105 -0
  147. package/src/lib/knowledge-exporter.js +381 -0
  148. package/src/lib/knowledge-graph.js +432 -0
  149. package/src/lib/knowledge-importer.js +379 -0
  150. package/src/lib/llm-providers.js +391 -0
  151. package/src/lib/matrix-bridge.js +105 -0
  152. package/src/lib/mcp-registry.js +333 -0
  153. package/src/lib/mcp-scaffold.js +81 -0
  154. package/src/lib/memory-injection.js +81 -0
  155. package/src/lib/memory-manager.js +330 -0
  156. package/src/lib/multimodal.js +346 -0
  157. package/src/lib/nl-programming.js +343 -0
  158. package/src/lib/nostr-bridge.js +105 -0
  159. package/src/lib/note-versioning.js +327 -0
  160. package/src/lib/orchestrator.js +105 -0
  161. package/src/lib/org-manager.js +323 -0
  162. package/src/lib/p2p-manager.js +387 -0
  163. package/src/lib/pdf-parser.js +81 -0
  164. package/src/lib/perception.js +346 -0
  165. package/src/lib/perf-tuning.js +109 -1
  166. package/src/lib/permanent-memory.js +320 -0
  167. package/src/lib/permission-engine.js +81 -0
  168. package/src/lib/pipeline-orchestrator.js +105 -0
  169. package/src/lib/plan-mode.js +81 -0
  170. package/src/lib/plugin-ecosystem.js +377 -0
  171. package/src/lib/pqc-manager.js +368 -0
  172. package/src/lib/prompt-compressor.js +1 -10
  173. package/src/lib/protocol-fusion.js +417 -0
  174. package/src/lib/quantization.js +325 -0
  175. package/src/lib/response-cache.js +327 -0
  176. package/src/lib/scim-manager.js +329 -0
  177. package/src/lib/service-container.js +81 -0
  178. package/src/lib/session-consolidator.js +105 -0
  179. package/src/lib/session-hooks.js +81 -0
  180. package/src/lib/session-manager.js +329 -0
  181. package/src/lib/session-search.js +81 -0
  182. package/src/lib/session-tail.js +81 -0
  183. package/src/lib/session-usage.js +83 -0
  184. package/src/lib/siem-exporter.js +105 -0
  185. package/src/lib/skill-loader.js +377 -0
  186. package/src/lib/slot-filler.js +81 -0
  187. package/src/lib/social-graph-analytics.js +81 -0
  188. package/src/lib/social-graph.js +81 -0
  189. package/src/lib/social-manager.js +326 -0
  190. package/src/lib/sso-manager.js +332 -0
  191. package/src/lib/sub-agent-registry.js +110 -0
  192. package/src/lib/sync-manager.js +326 -0
  193. package/src/lib/task-model-selector.js +81 -0
  194. package/src/lib/tech-learning-engine.js +369 -0
  195. package/src/lib/tenant-saas.js +460 -0
  196. package/src/lib/threat-intel.js +335 -0
  197. package/src/lib/todo-manager.js +105 -0
  198. package/src/lib/token-incentive.js +293 -0
  199. package/src/lib/token-tracker.js +329 -0
  200. package/src/lib/topic-classifier.js +105 -0
  201. package/src/lib/trust-security.js +390 -0
  202. package/src/lib/ueba.js +389 -0
  203. package/src/lib/universal-runtime.js +325 -0
  204. package/src/lib/user-profile.js +81 -0
  205. package/src/lib/version-checker.js +81 -0
  206. package/src/lib/wallet-manager.js +326 -0
  207. package/src/lib/web-fetch.js +81 -0
  208. package/src/lib/workflow-engine.js +322 -0
  209. package/src/lib/zkp-engine.js +105 -0
@@ -649,3 +649,372 @@ export function _resetState() {
649
649
  _practices.clear();
650
650
  _seq = 0;
651
651
  }
652
+
653
+ /* ═══════════════════════════════════════════════════════════════
654
+ * V2 Surface — Tech Learning Engine V2 (additive)
655
+ * State machines + caps + auto-flip for tech profiles / learning runs
656
+ * ═══════════════════════════════════════════════════════════════ */
657
+
658
+ export const PROFILE_MATURITY_V2 = Object.freeze({
659
+ DRAFT: "draft",
660
+ ACTIVE: "active",
661
+ STALE: "stale",
662
+ ARCHIVED: "archived",
663
+ });
664
+
665
+ export const LEARNING_RUN_V2 = Object.freeze({
666
+ QUEUED: "queued",
667
+ STUDYING: "studying",
668
+ COMPLETED: "completed",
669
+ ABANDONED: "abandoned",
670
+ FAILED: "failed",
671
+ });
672
+
673
+ const _PROFILE_TRANS_V2 = new Map([
674
+ [
675
+ PROFILE_MATURITY_V2.DRAFT,
676
+ new Set([PROFILE_MATURITY_V2.ACTIVE, PROFILE_MATURITY_V2.ARCHIVED]),
677
+ ],
678
+ [
679
+ PROFILE_MATURITY_V2.ACTIVE,
680
+ new Set([PROFILE_MATURITY_V2.STALE, PROFILE_MATURITY_V2.ARCHIVED]),
681
+ ],
682
+ [
683
+ PROFILE_MATURITY_V2.STALE,
684
+ new Set([PROFILE_MATURITY_V2.ACTIVE, PROFILE_MATURITY_V2.ARCHIVED]),
685
+ ],
686
+ [PROFILE_MATURITY_V2.ARCHIVED, new Set()],
687
+ ]);
688
+
689
+ const _RUN_TRANS_V2 = new Map([
690
+ [
691
+ LEARNING_RUN_V2.QUEUED,
692
+ new Set([
693
+ LEARNING_RUN_V2.STUDYING,
694
+ LEARNING_RUN_V2.ABANDONED,
695
+ LEARNING_RUN_V2.FAILED,
696
+ ]),
697
+ ],
698
+ [
699
+ LEARNING_RUN_V2.STUDYING,
700
+ new Set([
701
+ LEARNING_RUN_V2.COMPLETED,
702
+ LEARNING_RUN_V2.FAILED,
703
+ LEARNING_RUN_V2.ABANDONED,
704
+ ]),
705
+ ],
706
+ [LEARNING_RUN_V2.COMPLETED, new Set()],
707
+ [LEARNING_RUN_V2.ABANDONED, new Set()],
708
+ [LEARNING_RUN_V2.FAILED, new Set()],
709
+ ]);
710
+
711
+ const _PROFILE_TERMINAL_V2 = new Set([PROFILE_MATURITY_V2.ARCHIVED]);
712
+ const _RUN_TERMINAL_V2 = new Set([
713
+ LEARNING_RUN_V2.COMPLETED,
714
+ LEARNING_RUN_V2.ABANDONED,
715
+ LEARNING_RUN_V2.FAILED,
716
+ ]);
717
+
718
+ export const TLE_DEFAULT_MAX_ACTIVE_PROFILES_PER_OWNER = 10;
719
+ export const TLE_DEFAULT_MAX_STUDYING_RUNS_PER_LEARNER = 5;
720
+ export const TLE_DEFAULT_PROFILE_STALE_MS = 60 * 24 * 60 * 60 * 1000;
721
+ export const TLE_DEFAULT_RUN_STUCK_MS = 7 * 24 * 60 * 60 * 1000;
722
+
723
+ let _tleMaxActiveProfiles = TLE_DEFAULT_MAX_ACTIVE_PROFILES_PER_OWNER;
724
+ let _tleMaxStudyingRuns = TLE_DEFAULT_MAX_STUDYING_RUNS_PER_LEARNER;
725
+ let _tleProfileStaleMs = TLE_DEFAULT_PROFILE_STALE_MS;
726
+ let _tleRunStuckMs = TLE_DEFAULT_RUN_STUCK_MS;
727
+
728
+ const _profilesV2 = new Map();
729
+ const _runsV2 = new Map();
730
+
731
+ function _posIntV2(n, label) {
732
+ const v = Number.isInteger(n) ? n : Math.floor(n);
733
+ if (!Number.isFinite(v) || v <= 0)
734
+ throw new Error(`${label} must be a positive integer`);
735
+ return v;
736
+ }
737
+
738
+ export function getMaxActiveProfilesPerOwnerV2() {
739
+ return _tleMaxActiveProfiles;
740
+ }
741
+ export function setMaxActiveProfilesPerOwnerV2(n) {
742
+ _tleMaxActiveProfiles = _posIntV2(n, "maxActiveProfilesPerOwner");
743
+ return _tleMaxActiveProfiles;
744
+ }
745
+ export function getMaxStudyingRunsPerLearnerV2() {
746
+ return _tleMaxStudyingRuns;
747
+ }
748
+ export function setMaxStudyingRunsPerLearnerV2(n) {
749
+ _tleMaxStudyingRuns = _posIntV2(n, "maxStudyingRunsPerLearner");
750
+ return _tleMaxStudyingRuns;
751
+ }
752
+ export function getProfileStaleMsV2() {
753
+ return _tleProfileStaleMs;
754
+ }
755
+ export function setProfileStaleMsV2(n) {
756
+ _tleProfileStaleMs = _posIntV2(n, "profileStaleMs");
757
+ return _tleProfileStaleMs;
758
+ }
759
+ export function getRunStuckMsV2() {
760
+ return _tleRunStuckMs;
761
+ }
762
+ export function setRunStuckMsV2(n) {
763
+ _tleRunStuckMs = _posIntV2(n, "runStuckMs");
764
+ return _tleRunStuckMs;
765
+ }
766
+
767
+ export function getActiveProfileCountV2(owner) {
768
+ if (!owner) throw new Error("owner is required");
769
+ let c = 0;
770
+ for (const p of _profilesV2.values()) {
771
+ if (p.owner !== owner) continue;
772
+ if (p.status === PROFILE_MATURITY_V2.ARCHIVED) continue;
773
+ if (p.status === PROFILE_MATURITY_V2.DRAFT) continue;
774
+ c++;
775
+ }
776
+ return c;
777
+ }
778
+
779
+ export function getStudyingRunCountV2(learner) {
780
+ if (!learner) throw new Error("learner is required");
781
+ let c = 0;
782
+ for (const r of _runsV2.values()) {
783
+ if (r.learner !== learner) continue;
784
+ if (r.status !== LEARNING_RUN_V2.STUDYING) continue;
785
+ c++;
786
+ }
787
+ return c;
788
+ }
789
+
790
+ export function createProfileV2({ id, owner, stackName, metadata }) {
791
+ if (!id) throw new Error("id is required");
792
+ if (!owner) throw new Error("owner is required");
793
+ if (!stackName) throw new Error("stackName is required");
794
+ if (_profilesV2.has(id)) throw new Error(`profile ${id} already exists`);
795
+ const now = Date.now();
796
+ const profile = {
797
+ id,
798
+ owner,
799
+ stackName: String(stackName),
800
+ status: PROFILE_MATURITY_V2.DRAFT,
801
+ createdAt: now,
802
+ updatedAt: now,
803
+ activatedAt: null,
804
+ lastTouchedAt: now,
805
+ metadata: metadata ? { ...metadata } : {},
806
+ };
807
+ _profilesV2.set(id, profile);
808
+ return { ...profile, metadata: { ...profile.metadata } };
809
+ }
810
+
811
+ export function getProfileV2(id) {
812
+ const p = _profilesV2.get(id);
813
+ if (!p) return null;
814
+ return { ...p, metadata: { ...p.metadata } };
815
+ }
816
+
817
+ export function listProfilesV2({ owner, status } = {}) {
818
+ const out = [];
819
+ for (const p of _profilesV2.values()) {
820
+ if (owner && p.owner !== owner) continue;
821
+ if (status && p.status !== status) continue;
822
+ out.push({ ...p, metadata: { ...p.metadata } });
823
+ }
824
+ return out;
825
+ }
826
+
827
+ export function setProfileMaturityV2(
828
+ id,
829
+ nextStatus,
830
+ { reason, metadata } = {},
831
+ ) {
832
+ const p = _profilesV2.get(id);
833
+ if (!p) throw new Error(`profile ${id} not found`);
834
+ if (!_PROFILE_TRANS_V2.has(p.status))
835
+ throw new Error(`unknown status ${p.status}`);
836
+ const allowed = _PROFILE_TRANS_V2.get(p.status);
837
+ if (!allowed.has(nextStatus)) {
838
+ throw new Error(
839
+ `cannot transition profile ${id} from ${p.status} to ${nextStatus}`,
840
+ );
841
+ }
842
+ if (nextStatus === PROFILE_MATURITY_V2.ACTIVE && p.owner) {
843
+ const count = getActiveProfileCountV2(p.owner);
844
+ const wasActive =
845
+ p.status === PROFILE_MATURITY_V2.ACTIVE ||
846
+ p.status === PROFILE_MATURITY_V2.STALE;
847
+ if (!wasActive && count >= _tleMaxActiveProfiles) {
848
+ throw new Error(
849
+ `owner ${p.owner} exceeds max active profile cap ${_tleMaxActiveProfiles}`,
850
+ );
851
+ }
852
+ }
853
+ const now = Date.now();
854
+ p.status = nextStatus;
855
+ p.updatedAt = now;
856
+ p.lastTouchedAt = now;
857
+ if (nextStatus === PROFILE_MATURITY_V2.ACTIVE && !p.activatedAt)
858
+ p.activatedAt = now;
859
+ if (reason) p.reason = reason;
860
+ if (metadata) p.metadata = { ...p.metadata, ...metadata };
861
+ return { ...p, metadata: { ...p.metadata } };
862
+ }
863
+
864
+ export function activateProfileV2(id, opts) {
865
+ return setProfileMaturityV2(id, PROFILE_MATURITY_V2.ACTIVE, opts);
866
+ }
867
+ export function markProfileStaleV2(id, opts) {
868
+ return setProfileMaturityV2(id, PROFILE_MATURITY_V2.STALE, opts);
869
+ }
870
+ export function archiveProfileV2(id, opts) {
871
+ return setProfileMaturityV2(id, PROFILE_MATURITY_V2.ARCHIVED, opts);
872
+ }
873
+
874
+ export function touchProfileV2(id) {
875
+ const p = _profilesV2.get(id);
876
+ if (!p) throw new Error(`profile ${id} not found`);
877
+ if (_PROFILE_TERMINAL_V2.has(p.status))
878
+ throw new Error(`profile ${id} is terminal`);
879
+ p.lastTouchedAt = Date.now();
880
+ return { ...p, metadata: { ...p.metadata } };
881
+ }
882
+
883
+ export function enqueueRunV2({ id, learner, topic, metadata }) {
884
+ if (!id) throw new Error("id is required");
885
+ if (!learner) throw new Error("learner is required");
886
+ if (!topic) throw new Error("topic is required");
887
+ if (_runsV2.has(id)) throw new Error(`run ${id} already exists`);
888
+ const now = Date.now();
889
+ const run = {
890
+ id,
891
+ learner,
892
+ topic: String(topic),
893
+ status: LEARNING_RUN_V2.QUEUED,
894
+ createdAt: now,
895
+ updatedAt: now,
896
+ startedAt: null,
897
+ endedAt: null,
898
+ metadata: metadata ? { ...metadata } : {},
899
+ };
900
+ _runsV2.set(id, run);
901
+ return { ...run, metadata: { ...run.metadata } };
902
+ }
903
+
904
+ export function getRunV2(id) {
905
+ const r = _runsV2.get(id);
906
+ if (!r) return null;
907
+ return { ...r, metadata: { ...r.metadata } };
908
+ }
909
+
910
+ export function listRunsV2({ learner, status } = {}) {
911
+ const out = [];
912
+ for (const r of _runsV2.values()) {
913
+ if (learner && r.learner !== learner) continue;
914
+ if (status && r.status !== status) continue;
915
+ out.push({ ...r, metadata: { ...r.metadata } });
916
+ }
917
+ return out;
918
+ }
919
+
920
+ export function setRunStatusV2(id, nextStatus, { reason, metadata } = {}) {
921
+ const r = _runsV2.get(id);
922
+ if (!r) throw new Error(`run ${id} not found`);
923
+ if (!_RUN_TRANS_V2.has(r.status))
924
+ throw new Error(`unknown status ${r.status}`);
925
+ const allowed = _RUN_TRANS_V2.get(r.status);
926
+ if (!allowed.has(nextStatus)) {
927
+ throw new Error(
928
+ `cannot transition run ${id} from ${r.status} to ${nextStatus}`,
929
+ );
930
+ }
931
+ if (nextStatus === LEARNING_RUN_V2.STUDYING) {
932
+ const count = getStudyingRunCountV2(r.learner);
933
+ if (count >= _tleMaxStudyingRuns) {
934
+ throw new Error(
935
+ `learner ${r.learner} exceeds max studying run cap ${_tleMaxStudyingRuns}`,
936
+ );
937
+ }
938
+ }
939
+ const now = Date.now();
940
+ r.status = nextStatus;
941
+ r.updatedAt = now;
942
+ if (nextStatus === LEARNING_RUN_V2.STUDYING && !r.startedAt)
943
+ r.startedAt = now;
944
+ if (_RUN_TERMINAL_V2.has(nextStatus)) r.endedAt = now;
945
+ if (reason) r.reason = reason;
946
+ if (metadata) r.metadata = { ...r.metadata, ...metadata };
947
+ return { ...r, metadata: { ...r.metadata } };
948
+ }
949
+
950
+ export function startRunV2(id, opts) {
951
+ return setRunStatusV2(id, LEARNING_RUN_V2.STUDYING, opts);
952
+ }
953
+ export function completeRunV2(id, opts) {
954
+ return setRunStatusV2(id, LEARNING_RUN_V2.COMPLETED, opts);
955
+ }
956
+ export function abandonRunV2(id, opts) {
957
+ return setRunStatusV2(id, LEARNING_RUN_V2.ABANDONED, opts);
958
+ }
959
+ export function failRunV2(id, opts) {
960
+ return setRunStatusV2(id, LEARNING_RUN_V2.FAILED, opts);
961
+ }
962
+
963
+ export function autoMarkStaleProfilesV2({ now } = {}) {
964
+ const t = now ?? Date.now();
965
+ const out = [];
966
+ for (const p of _profilesV2.values()) {
967
+ if (p.status !== PROFILE_MATURITY_V2.ACTIVE) continue;
968
+ if (t - p.lastTouchedAt > _tleProfileStaleMs) {
969
+ p.status = PROFILE_MATURITY_V2.STALE;
970
+ p.updatedAt = t;
971
+ out.push(p.id);
972
+ }
973
+ }
974
+ return out;
975
+ }
976
+
977
+ export function autoFailStuckRunsV2({ now } = {}) {
978
+ const t = now ?? Date.now();
979
+ const out = [];
980
+ for (const r of _runsV2.values()) {
981
+ if (r.status !== LEARNING_RUN_V2.STUDYING) continue;
982
+ if (r.startedAt == null) continue;
983
+ if (t - r.startedAt > _tleRunStuckMs) {
984
+ r.status = LEARNING_RUN_V2.FAILED;
985
+ r.endedAt = t;
986
+ r.updatedAt = t;
987
+ r.reason = r.reason || "auto-fail: stuck studying";
988
+ out.push(r.id);
989
+ }
990
+ }
991
+ return out;
992
+ }
993
+
994
+ export function getTechLearningStatsV2() {
995
+ const profilesByStatus = {};
996
+ for (const v of Object.values(PROFILE_MATURITY_V2)) profilesByStatus[v] = 0;
997
+ for (const p of _profilesV2.values()) profilesByStatus[p.status]++;
998
+ const runsByStatus = {};
999
+ for (const v of Object.values(LEARNING_RUN_V2)) runsByStatus[v] = 0;
1000
+ for (const r of _runsV2.values()) runsByStatus[r.status]++;
1001
+ return {
1002
+ totalProfilesV2: _profilesV2.size,
1003
+ totalRunsV2: _runsV2.size,
1004
+ maxActiveProfilesPerOwner: _tleMaxActiveProfiles,
1005
+ maxStudyingRunsPerLearner: _tleMaxStudyingRuns,
1006
+ profileStaleMs: _tleProfileStaleMs,
1007
+ runStuckMs: _tleRunStuckMs,
1008
+ profilesByStatus,
1009
+ runsByStatus,
1010
+ };
1011
+ }
1012
+
1013
+ export function _resetStateV2() {
1014
+ _profilesV2.clear();
1015
+ _runsV2.clear();
1016
+ _tleMaxActiveProfiles = TLE_DEFAULT_MAX_ACTIVE_PROFILES_PER_OWNER;
1017
+ _tleMaxStudyingRuns = TLE_DEFAULT_MAX_STUDYING_RUNS_PER_LEARNER;
1018
+ _tleProfileStaleMs = TLE_DEFAULT_PROFILE_STALE_MS;
1019
+ _tleRunStuckMs = TLE_DEFAULT_RUN_STUCK_MS;
1020
+ }