chainlesschain 0.162.149 → 0.162.150

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 (273) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-BJif14yR.js → AIOps-CBLvrjeG.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-CXek6gJY.js → ActionButton-DYv2GtE0.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-BgQhdAJi.js → Analytics-CL6PZ-Ww.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-DTYl5NtR.js → AppLayout-xuyHt4uA.js} +3 -3
  6. package/src/assets/web-panel/assets/{Audit-BzATQAeR.js → Audit-DOvSVycq.js} +1 -1
  7. package/src/assets/web-panel/assets/{Backup-BzdPEQhL.js → Backup-DMhfTswr.js} +1 -1
  8. package/src/assets/web-panel/assets/{BaseInput-BM0KVh8E.js → BaseInput-CQxDdm63.js} +1 -1
  9. package/src/assets/web-panel/assets/{Chat-D7fHXHkz.js → Chat-BEeNhK2a.js} +5 -5
  10. package/src/assets/web-panel/assets/{ChatBubbleRenderer-Wm34RR-b.js → ChatBubbleRenderer-8nul8eTq.js} +1 -1
  11. package/src/assets/web-panel/assets/{Checkbox-CAiSQ9vO.js → Checkbox-CL04O-ER.js} +1 -1
  12. package/src/assets/web-panel/assets/{Codegen-Df40CrEe.js → Codegen-C50o-n7x.js} +1 -1
  13. package/src/assets/web-panel/assets/{Col-DIT2fNFU.js → Col-CH-bDkzs.js} +1 -1
  14. package/src/assets/web-panel/assets/{Community-CSTIbW2k.js → Community-DqAIMvSe.js} +1 -1
  15. package/src/assets/web-panel/assets/{Compact-DtqXZZUi.js → Compact-C43fo_my.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compliance-CUtzw6o7.js → Compliance-BERnMrdP.js} +1 -1
  17. package/src/assets/web-panel/assets/{Cowork-CezmlnmU.js → Cowork-Baw3w1gp.js} +4 -4
  18. package/src/assets/web-panel/assets/{Cron-P4BITarg.js → Cron-BEqAHF1-.js} +2 -2
  19. package/src/assets/web-panel/assets/{Crosschain-BRRiYwvq.js → Crosschain-CvnmKwK4.js} +1 -1
  20. package/src/assets/web-panel/assets/{DID-L5ijB9i4.js → DID-iMPxgVdt.js} +2 -2
  21. package/src/assets/web-panel/assets/{Dashboard-CFxro4ob.js → Dashboard--4SJX3YR.js} +2 -2
  22. package/src/assets/web-panel/assets/{Dropdown-BmAFCQ71.js → Dropdown-BgLV6xgz.js} +1 -1
  23. package/src/assets/web-panel/assets/{EmailListRenderer-DJBCEuon.js → EmailListRenderer-Bvb8oUD8.js} +1 -1
  24. package/src/assets/web-panel/assets/{FamilyGuardDashboard-z4oLq6eT.js → FamilyGuardDashboard-DpXPjJB5.js} +1 -1
  25. package/src/assets/web-panel/assets/{Federation-DsVCpHMF.js → Federation-BbFfJ1Xi.js} +1 -1
  26. package/src/assets/web-panel/assets/{FormItemContext-DP3bP5th.js → FormItemContext-DeGq1B-q.js} +1 -1
  27. package/src/assets/web-panel/assets/{GenericCardRenderer-BAXP2Gc6.js → GenericCardRenderer-CNW7s9zM.js} +1 -1
  28. package/src/assets/web-panel/assets/{Git-I3g_bAw9.js → Git-L1PjW-lT.js} +2 -2
  29. package/src/assets/web-panel/assets/{Governance-jHS5-ioS.js → Governance-PK-X58to.js} +1 -1
  30. package/src/assets/web-panel/assets/{Inference-CPL7sfx9.js → Inference-BePWEH-d.js} +1 -1
  31. package/src/assets/web-panel/assets/{KnowledgeGraph-Jf236h4C.js → KnowledgeGraph-LF_sBvdL.js} +1 -1
  32. package/src/assets/web-panel/assets/{Logs-Cm2tcSKg.js → Logs-BKkfk9hy.js} +2 -2
  33. package/src/assets/web-panel/assets/{Marketplace-CZK82rhi.js → Marketplace-BNMqUDla.js} +1 -1
  34. package/src/assets/web-panel/assets/{McpTools-CZCeji7a.js → McpTools-w4WPiyz2.js} +5 -5
  35. package/src/assets/web-panel/assets/{Memory-3l2KVS9k.js → Memory-DUKMVGNi.js} +2 -2
  36. package/src/assets/web-panel/assets/{MobileBridge-VYdpoLh6.js → MobileBridge-BWhiEyTJ.js} +1 -1
  37. package/src/assets/web-panel/assets/{MobileProjects-CiB9cmm1.js → MobileProjects-Ocf5JEkX.js} +1 -1
  38. package/src/assets/web-panel/assets/{Mtc-wCFZbBuL.js → Mtc-D2B6MMhU.js} +4 -4
  39. package/src/assets/web-panel/assets/{MtcAudit-1a3THIyG.js → MtcAudit-DdYjCq1O.js} +2 -2
  40. package/src/assets/web-panel/assets/{Multisig-DMzLB2hG.js → Multisig-Cb1hfuUZ.js} +3 -3
  41. package/src/assets/web-panel/assets/{NLProgramming-D9wZbf6l.js → NLProgramming-CTeImGp7.js} +1 -1
  42. package/src/assets/web-panel/assets/{Notes-hrFe2ZM-.js → Notes-BjYNc7eQ.js} +4 -4
  43. package/src/assets/web-panel/assets/{NotificationSettings-CHGX5Jwm.js → NotificationSettings-Dn_NtRXQ.js} +1 -1
  44. package/src/assets/web-panel/assets/OrderTableRenderer-DVYYIizh.js +1 -0
  45. package/src/assets/web-panel/assets/{Organization-By7FkhtY.js → Organization-Be2Kmr5j.js} +4 -4
  46. package/src/assets/web-panel/assets/{Overflow--khGSzJn.js → Overflow-Cu_-qRlR.js} +1 -1
  47. package/src/assets/web-panel/assets/{P2P-CAG9dH35.js → P2P-DD2HoGzE.js} +2 -2
  48. package/src/assets/web-panel/assets/{PdhVaultBrowser-B3SQZmK9.js → PdhVaultBrowser-BRI7DVth.js} +3 -3
  49. package/src/assets/web-panel/assets/{Permissions-D35ec6JA.js → Permissions-C9Srcs2M.js} +3 -3
  50. package/src/assets/web-panel/assets/{PersonalDataHub-CxBF7hW_.js → PersonalDataHub-CUqcMgo1.js} +3 -3
  51. package/src/assets/web-panel/assets/{Pipeline-s6EtOO1s.js → Pipeline-HBrQGLXt.js} +1 -1
  52. package/src/assets/web-panel/assets/{Privacy-BbJYmWmO.js → Privacy-D-B0vjwh.js} +1 -1
  53. package/src/assets/web-panel/assets/{ProjectInit-VGQq1jMT.js → ProjectInit-eTeLIu9e.js} +2 -2
  54. package/src/assets/web-panel/assets/{ProjectSettings-B1ew3Teh.js → ProjectSettings-DrRqCsC6.js} +2 -2
  55. package/src/assets/web-panel/assets/Projects-1G9DNOhI.js +1 -0
  56. package/src/assets/web-panel/assets/{Providers-mrO47FIK.js → Providers-RkTZzpxP.js} +1 -1
  57. package/src/assets/web-panel/assets/{QrScannerModal-IJF2mHyw.js → QrScannerModal-BSCUgsgC.js} +1 -1
  58. package/src/assets/web-panel/assets/{QuickAsk-CU0wN_Z0.js → QuickAsk-CHgyM3Bz.js} +1 -1
  59. package/src/assets/web-panel/assets/{Recommend-DhN37R6G.js → Recommend-0lry4OZq.js} +1 -1
  60. package/src/assets/web-panel/assets/{RemoteSession-D_xOX_hu.js → RemoteSession-Cn45UroZ.js} +2 -2
  61. package/src/assets/web-panel/assets/{Reputation-D_Ssv7uH.js → Reputation-Q-Zjb707.js} +1 -1
  62. package/src/assets/web-panel/assets/{Row-Kx5dKxX7.js → Row-BdM70oda.js} +1 -1
  63. package/src/assets/web-panel/assets/{RssFeed-BlGwqZkY.js → RssFeed-DmOAKKap.js} +2 -2
  64. package/src/assets/web-panel/assets/{Search-hLFQzxpb.js → Search-Dwavbm07.js} +1 -1
  65. package/src/assets/web-panel/assets/{Security-DMlvsVt4.js → Security-DukXFCnk.js} +3 -3
  66. package/src/assets/web-panel/assets/{Services-Bd0Qsj2m.js → Services-BIlRnITu.js} +2 -2
  67. package/src/assets/web-panel/assets/{Skeleton-DFclq9X3.js → Skeleton-YYVQdhhQ.js} +1 -1
  68. package/src/assets/web-panel/assets/{Skills-BNtln2qY.js → Skills-B8_iYHz2.js} +1 -1
  69. package/src/assets/web-panel/assets/{Sla-Dch5H19G.js → Sla-BdVrhT31.js} +1 -1
  70. package/src/assets/web-panel/assets/{SpeechSettings-2UfQcU1g.js → SpeechSettings-CD3ggRx7.js} +1 -1
  71. package/src/assets/web-panel/assets/{SyncSettings-CD9YQr4i.js → SyncSettings-Bp02VZFH.js} +2 -2
  72. package/src/assets/web-panel/assets/{Tasks-BNu-7MzI.js → Tasks-DEVmCEsr.js} +1 -1
  73. package/src/assets/web-panel/assets/{Templates-D1n9CaIR.js → Templates-B6czWc4N.js} +1 -1
  74. package/src/assets/web-panel/assets/{Tenant-DenL3iBW.js → Tenant-BCJLv17r.js} +1 -1
  75. package/src/assets/web-panel/assets/{Terminal-ZzU0Io1Y.js → Terminal-CD132d2Y.js} +2 -2
  76. package/src/assets/web-panel/assets/{TimelineRenderer-D87IfukO.js → TimelineRenderer-ZB-CvkZl.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tokens-BkiZc8E3.js → Tokens-BnSY0S-s.js} +1 -1
  78. package/src/assets/web-panel/assets/{Trigger-BNRSytGN.js → Trigger-VZw9Oy2w.js} +1 -1
  79. package/src/assets/web-panel/assets/{Trust-Bwbd4X2m.js → Trust-pZq7Hjd2.js} +1 -1
  80. package/src/assets/web-panel/assets/{UkeySign-B8O2bs0o.js → UkeySign-DnQaqk4q.js} +1 -1
  81. package/src/assets/web-panel/assets/{VideoEditing-C2fL8zmH.js → VideoEditing-BEUfmvJV.js} +1 -1
  82. package/src/assets/web-panel/assets/{Wallet-BORYDdE1.js → Wallet-CoZKMXJ2.js} +4 -4
  83. package/src/assets/web-panel/assets/{WebAuthn-C0V5S2FM.js → WebAuthn-CBOGVx1I.js} +5 -5
  84. package/src/assets/web-panel/assets/{WorkflowEditor-2dR0fcHL.js → WorkflowEditor-huSKn7TT.js} +1 -1
  85. package/src/assets/web-panel/assets/{chat-BmuAFAn8.js → chat-A_3w6FBO.js} +1 -1
  86. package/src/assets/web-panel/assets/{colors-CN3smMcK.js → colors-D1Bem9Oy.js} +1 -1
  87. package/src/assets/web-panel/assets/{compact-item-DCnxb4kW.js → compact-item-CJYJj0oO.js} +1 -1
  88. package/src/assets/web-panel/assets/{createContext-vlR43pHn.js → createContext-BkbFiKT4.js} +1 -1
  89. package/src/assets/web-panel/assets/devWarning-WDr3_M_N.js +1 -0
  90. package/src/assets/web-panel/assets/{hasIn-D04tHYFd.js → hasIn-CKvUafVY.js} +1 -1
  91. package/src/assets/web-panel/assets/{index-0DnaZGkC.js → index-AjrSPnvv.js} +1 -1
  92. package/src/assets/web-panel/assets/{index-BudvKQfG.js → index-B8i0lViZ.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-BeGDEXFs.js → index-B9Svn0zc.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-D5LZVZ0L.js → index-BHdHSX06.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-BTPEZTk1.js → index-BHdailyo.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-DIpY0qM5.js → index-BJwlEnYo.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-CsAsCPJ6.js → index-BOoAQjJz.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-ljuBiQW9.js → index-BSgWxAOG.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-hpvvtAZ3.js → index-BdutMsne.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-_FIkN3jd.js → index-BiDWxzbn.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-C-6NO5il.js → index-By5a0T_W.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-B78xL3s2.js → index-C-WIY-FQ.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-ClhAHDK3.js → index-C37f6iey.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-ToUh2b1-.js → index-C9bWmTcO.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-D28DeAAB.js → index-CBaosWRO.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-D8vwp4qp.js → index-CBlBVJ_m.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BqhASEL4.js → index-CD62EEGo.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DDwLgQY9.js → index-CUj-l7GM.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-DbVsQBOH.js → index-CVS8Ymuq.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Cr-A0FYJ.js → index-ChkXUj3f.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-D65_XseV.js → index-Cj0OZ-37.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BXRg8GFQ.js → index-Co3OFL0t.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-430S68MN.js → index-Crp8CbRg.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CngCC8hC.js → index-D22zNXiS.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-HhNjnCfe.js → index-DTs_D1OL.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CP9m9Ggr.js → index-DfgCdFrN.js} +3 -3
  117. package/src/assets/web-panel/assets/{index-jzR7Ujuw.js → index-DjYrecNb.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CTOCnIQ7.js → index-DpW9cf3e.js} +1 -1
  119. package/src/assets/web-panel/assets/index-Dwix3p4g.js +1 -0
  120. package/src/assets/web-panel/assets/{index-D_n8_vfI.js → index-F--HuPG1.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-BasvsWDM.js → index-Fuk6t_3K.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CnXebZLL.js → index-JEAGMii9.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DYAtmqiv.js → index-PF-mpv8K.js} +1 -1
  124. package/src/assets/web-panel/assets/index-SHaoZ0CA.js +1 -0
  125. package/src/assets/web-panel/assets/{index-DTWg-18U.js → index-b-sbVdjQ.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-C5Sxb1sE.js → index-pyvMVX8r.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-TslMTwNy.js → index-qNTtOVi_.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-DTtRscUa.js → index-tgO8iza6.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DbADHwhr.js → index-ttDQVhZy.js} +1 -1
  130. package/src/assets/web-panel/assets/{initDefaultProps-C3wUb4je.js → initDefaultProps-DtrnfsZH.js} +1 -1
  131. package/src/assets/web-panel/assets/{motion-D-jYFUNA.js → motion-D4zqSaX3.js} +1 -1
  132. package/src/assets/web-panel/assets/{move-tqb8nwJ2.js → move-CGFGOUQj.js} +1 -1
  133. package/src/assets/web-panel/assets/{mtc-parser-DSOjMJMz.js → mtc-parser-DH2HvkJl.js} +1 -1
  134. package/src/assets/web-panel/assets/{omit-CJ7VimIW.js → omit-jJ2at5HX.js} +1 -1
  135. package/src/assets/web-panel/assets/{pickAttrs-qXiG1iT3.js → pickAttrs-CRyMT1Fv.js} +1 -1
  136. package/src/assets/web-panel/assets/{placementArrow-CkGBcy1Z.js → placementArrow-DZ_CX0Pt.js} +1 -1
  137. package/src/assets/web-panel/assets/{responsiveObserve-D3WvTlLO.js → responsiveObserve-wruHk-h5.js} +1 -1
  138. package/src/assets/web-panel/assets/{slide-BEE2ftge.js → slide-BGgx8q67.js} +1 -1
  139. package/src/assets/web-panel/assets/{statusUtils-CsfBpxiG.js → statusUtils-Do5M7gKm.js} +1 -1
  140. package/src/assets/web-panel/assets/{styleChecker-xPrIiJPI.js → styleChecker-CRa-GZpX.js} +1 -1
  141. package/src/assets/web-panel/assets/{useFlexGapSupport-C5Yd-SCR.js → useFlexGapSupport-BxPcq6pj.js} +1 -1
  142. package/src/assets/web-panel/assets/{useFs-D_MDS8HI.js → useFs-v5O2ZcJm.js} +1 -1
  143. package/src/assets/web-panel/assets/{usePersonalDataHub-BqJh-usA.js → usePersonalDataHub--z2FU0Px.js} +1 -1
  144. package/src/assets/web-panel/assets/{vnode-chm_p-gz.js → vnode-1emidVKd.js} +1 -1
  145. package/src/assets/web-panel/assets/{zoom-3-YDNz0Z.js → zoom-CcJaRyHs.js} +1 -1
  146. package/src/assets/web-panel/index.html +1 -1
  147. package/src/commands/a2a.js +19 -4
  148. package/src/commands/activitypub.js +20 -3
  149. package/src/commands/agent.js +27 -5
  150. package/src/commands/audit.js +40 -24
  151. package/src/commands/codeintel.js +68 -0
  152. package/src/commands/collab.js +15 -2
  153. package/src/commands/compliance.js +5 -0
  154. package/src/commands/config.js +4 -1
  155. package/src/commands/dao.js +86 -14
  156. package/src/commands/dev.js +2 -0
  157. package/src/commands/did.js +7 -1
  158. package/src/commands/dlp.js +23 -1
  159. package/src/commands/economy.js +29 -3
  160. package/src/commands/eval.js +7 -0
  161. package/src/commands/evomap.js +26 -0
  162. package/src/commands/governance.js +17 -3
  163. package/src/commands/hardening.js +18 -0
  164. package/src/commands/incentive.js +5 -0
  165. package/src/commands/init.js +46 -2
  166. package/src/commands/kg.js +4 -0
  167. package/src/commands/loop.js +6 -1
  168. package/src/commands/lowcode.js +15 -2
  169. package/src/commands/marketplace.js +40 -6
  170. package/src/commands/matrix.js +20 -1
  171. package/src/commands/memory.js +4 -1
  172. package/src/commands/mtc.js +7 -1
  173. package/src/commands/nostr.js +31 -4
  174. package/src/commands/note.js +7 -4
  175. package/src/commands/plugin.js +125 -5
  176. package/src/commands/pqc.js +5 -0
  177. package/src/commands/reputation.js +10 -1
  178. package/src/commands/scim.js +6 -0
  179. package/src/commands/session.js +32 -10
  180. package/src/commands/siem.js +11 -0
  181. package/src/commands/sla.js +18 -3
  182. package/src/commands/social.js +38 -5
  183. package/src/commands/sso.js +10 -2
  184. package/src/commands/stress.js +23 -4
  185. package/src/commands/team.js +9 -2
  186. package/src/commands/tech.js +2 -0
  187. package/src/commands/tenant.js +10 -1
  188. package/src/commands/terraform.js +6 -0
  189. package/src/commands/update.js +1 -1
  190. package/src/commands/zkp.js +20 -0
  191. package/src/gateways/ws/message-dispatcher.js +5 -2
  192. package/src/gateways/ws/remote-session-protocol.js +103 -42
  193. package/src/harness/jsonl-session-store.js +12 -5
  194. package/src/harness/plugin-manager.js +16 -4
  195. package/src/harness/remote-command-ledger.js +46 -15
  196. package/src/harness/worktree-isolator.js +16 -6
  197. package/src/lib/__tests__/logger.test.js +5 -2
  198. package/src/lib/a2a-protocol.js +25 -1
  199. package/src/lib/activitypub-bridge.js +61 -0
  200. package/src/lib/agent-core.js +2 -0
  201. package/src/lib/agent-economy.js +262 -29
  202. package/src/lib/agent-network.js +7 -1
  203. package/src/lib/agent-team/team-runner.js +25 -9
  204. package/src/lib/agent-team/team-worktree.js +36 -4
  205. package/src/lib/async-hook-supervisor.cjs +102 -16
  206. package/src/lib/audit-logger.js +7 -6
  207. package/src/lib/autonomous-developer.js +60 -0
  208. package/src/lib/chat-core.js +17 -4
  209. package/src/lib/collaboration-governance.js +56 -0
  210. package/src/lib/community-governance.js +68 -0
  211. package/src/lib/compliance-manager.js +63 -0
  212. package/src/lib/cross-chain.js +5 -0
  213. package/src/lib/dao-governance.js +151 -2
  214. package/src/lib/did-manager.js +23 -10
  215. package/src/lib/dlp-engine.js +70 -0
  216. package/src/lib/eval/runner.js +89 -1
  217. package/src/lib/eval/tasks.js +170 -0
  218. package/src/lib/eval/trend.js +16 -1
  219. package/src/lib/evolution-system.js +92 -0
  220. package/src/lib/evomap-federation.js +55 -0
  221. package/src/lib/evomap-governance.js +94 -0
  222. package/src/lib/fatal-handler.js +17 -1
  223. package/src/lib/hardening-manager.js +73 -0
  224. package/src/lib/hierarchical-memory.js +14 -8
  225. package/src/lib/knowledge-exporter.js +8 -2
  226. package/src/lib/knowledge-graph.js +79 -0
  227. package/src/lib/llm-providers.js +23 -14
  228. package/src/lib/logger.js +4 -1
  229. package/src/lib/lsp/__tests__/benchmark.test.js +88 -0
  230. package/src/lib/lsp/__tests__/lsp-client.test.js +11 -0
  231. package/src/lib/lsp/__tests__/lsp-manager.test.js +69 -0
  232. package/src/lib/lsp/benchmark.js +257 -0
  233. package/src/lib/lsp/lsp-client.js +30 -9
  234. package/src/lib/lsp/lsp-manager.js +54 -2
  235. package/src/lib/matrix-bridge.js +84 -0
  236. package/src/lib/memory-manager.js +5 -3
  237. package/src/lib/nostr-bridge.js +53 -0
  238. package/src/lib/permission-engine.js +22 -4
  239. package/src/lib/plugin-runtime/__tests__/remote-source.test.js +256 -0
  240. package/src/lib/plugin-runtime/install.js +9 -1
  241. package/src/lib/plugin-runtime/policy.js +9 -1
  242. package/src/lib/plugin-runtime/remote-source.js +240 -0
  243. package/src/lib/pqc-manager.js +64 -0
  244. package/src/lib/reputation-optimizer.js +101 -0
  245. package/src/lib/sandbox-egress-proxy.js +159 -59
  246. package/src/lib/sandbox-fs-policy.js +112 -0
  247. package/src/lib/sandbox-network-policy.js +18 -1
  248. package/src/lib/sandbox-v2.js +14 -14
  249. package/src/lib/scim-manager.js +36 -0
  250. package/src/lib/session-manager.js +5 -2
  251. package/src/lib/settings-hooks.cjs +1 -0
  252. package/src/lib/siem-exporter.js +45 -0
  253. package/src/lib/skill-loader.js +20 -2
  254. package/src/lib/skill-marketplace.js +83 -0
  255. package/src/lib/sla-manager.js +88 -0
  256. package/src/lib/social-manager.js +74 -0
  257. package/src/lib/stress-tester.js +65 -0
  258. package/src/lib/tech-learning-engine.js +75 -0
  259. package/src/lib/tenant-saas.js +107 -0
  260. package/src/lib/terraform-manager.js +67 -0
  261. package/src/lib/token-incentive.js +180 -29
  262. package/src/lib/wallet-manager.js +81 -35
  263. package/src/lib/zkp-engine.js +87 -0
  264. package/src/repl/agent-repl.js +17 -2
  265. package/src/runtime/__tests__/auto-pin.test.js +104 -0
  266. package/src/runtime/agent-core.js +241 -68
  267. package/src/runtime/auto-pin.js +117 -0
  268. package/src/runtime/headless-runner.js +35 -0
  269. package/src/assets/web-panel/assets/OrderTableRenderer-CRIFE2Tj.js +0 -1
  270. package/src/assets/web-panel/assets/Projects-CGcNIs_g.js +0 -1
  271. package/src/assets/web-panel/assets/devWarning-DxwmsL4j.js +0 -1
  272. package/src/assets/web-panel/assets/index-Cg2ldRfU.js +0 -1
  273. package/src/assets/web-panel/assets/index-Dwzo-dtJ.js +0 -1
@@ -16,10 +16,25 @@
16
16
  /** Normalize one `cc eval` summary into a compact trend record. */
17
17
  export function summarizeRun(record, { ranAt = null, label = null } = {}) {
18
18
  const results = Array.isArray(record?.results) ? record.results : [];
19
- const perTask = {};
19
+ let perTask = {};
20
20
  for (const r of results) {
21
21
  if (r && r.id != null) perTask[r.id] = r.pass === true;
22
22
  }
23
+ // Idempotency: an already-summarized record carries `perTask` but NO
24
+ // `results` (that's exactly this function's own output shape). computeTrend
25
+ // documents "already-summarized" records as valid input and re-runs every
26
+ // record through summarizeRun — so if we always rebuilt perTask from
27
+ // `results` alone, a summarized record would come back with an EMPTY perTask,
28
+ // silently erasing every per-task regression/fix/drop and making the release
29
+ // gate report "no regression" when there was one. Preserve the record's own
30
+ // perTask when it has no results to derive from.
31
+ if (
32
+ results.length === 0 &&
33
+ record?.perTask &&
34
+ typeof record.perTask === "object"
35
+ ) {
36
+ perTask = { ...record.perTask };
37
+ }
23
38
  const total = Number.isFinite(record?.total) ? record.total : results.length;
24
39
  const passed = Number.isFinite(record?.passed)
25
40
  ? record.passed
@@ -63,6 +63,79 @@ export function ensureEvolutionTables(db) {
63
63
  `);
64
64
  }
65
65
 
66
+ /**
67
+ * Rehydrate the capabilities/models/growthLog stores from the persisted
68
+ * evolution_* tables. The `cc` CLI runs every command in a fresh process, so
69
+ * without this the Maps/array start empty and a capability/model/growth event
70
+ * recorded in a prior invocation is invisible (`cc evolution stats`/`growth`
71
+ * report nothing; `cc evolution export <id>` throws "not found"; `diagnose`
72
+ * always reports healthy/idle). It also lets assessCapability find an existing
73
+ * capability by name across processes instead of minting a fresh id each time
74
+ * (which would leave duplicate persisted rows). Call after
75
+ * ensureEvolutionTables(db). (diagnoses is write-only — no reader — so it is
76
+ * not rehydrated.)
77
+ */
78
+ export function loadFromDb(db) {
79
+ if (!db) return 0;
80
+ capabilities.clear();
81
+ models.clear();
82
+ growthLog.length = 0;
83
+
84
+ const capRows = db.prepare(`SELECT * FROM evolution_capabilities`).all();
85
+ for (const row of capRows) {
86
+ let history = [];
87
+ try {
88
+ history = row.history ? JSON.parse(row.history) : [];
89
+ } catch {
90
+ history = [];
91
+ }
92
+ // keyed by name (matches assessCapability)
93
+ capabilities.set(row.name, {
94
+ id: row.id,
95
+ name: row.name,
96
+ score: row.score ?? 0,
97
+ category: row.category,
98
+ trend: row.trend,
99
+ history,
100
+ });
101
+ }
102
+
103
+ const modelRows = db.prepare(`SELECT * FROM evolution_models`).all();
104
+ for (const row of modelRows) {
105
+ let parameters = {};
106
+ try {
107
+ parameters = row.parameters ? JSON.parse(row.parameters) : {};
108
+ } catch {
109
+ parameters = {};
110
+ }
111
+ // keyed by id (matches trainIncremental modelId)
112
+ models.set(row.id, {
113
+ id: row.id,
114
+ name: row.name,
115
+ type: row.type,
116
+ accuracy: row.accuracy ?? 0.5,
117
+ dataPoints: row.data_points ?? 0,
118
+ parameters,
119
+ createdAt: row.created_at ?? null,
120
+ updatedAt: row.updated_at ?? null,
121
+ });
122
+ }
123
+
124
+ const logRows = db.prepare(`SELECT * FROM evolution_growth_log`).all();
125
+ for (const row of logRows) {
126
+ growthLog.push({
127
+ id: row.id,
128
+ eventType: row.event_type,
129
+ description: row.description,
130
+ capabilityId: row.capability_id ?? null,
131
+ delta: row.delta ?? 0,
132
+ timestamp: row.timestamp,
133
+ });
134
+ }
135
+
136
+ return capabilities.size + models.size + growthLog.length;
137
+ }
138
+
66
139
  // ─── Core functions ───────────────────────────────────────────
67
140
 
68
141
  /**
@@ -70,6 +143,7 @@ export function ensureEvolutionTables(db) {
70
143
  */
71
144
  export function assessCapability(db, name, score, category = "general") {
72
145
  ensureEvolutionTables(db);
146
+ loadFromDb(db);
73
147
 
74
148
  let cap = capabilities.get(name);
75
149
  if (!cap) {
@@ -151,6 +225,7 @@ export function assessCapability(db, name, score, category = "general") {
151
225
  */
152
226
  export function trainIncremental(db, modelId, newData, options = {}) {
153
227
  ensureEvolutionTables(db);
228
+ loadFromDb(db);
154
229
 
155
230
  let model = models.get(modelId);
156
231
  if (!model) {
@@ -217,6 +292,7 @@ export function trainIncremental(db, modelId, newData, options = {}) {
217
292
  */
218
293
  export function selfDiagnose(db) {
219
294
  ensureEvolutionTables(db);
295
+ loadFromDb(db);
220
296
 
221
297
  const components = [];
222
298
  const issues = [];
@@ -327,6 +403,7 @@ export function selfDiagnose(db) {
327
403
  */
328
404
  export function selfRepair(db, issue) {
329
405
  ensureEvolutionTables(db);
406
+ loadFromDb(db);
330
407
 
331
408
  const actions = [];
332
409
  const timestamp = new Date().toISOString();
@@ -349,6 +426,10 @@ export function selfRepair(db, issue) {
349
426
  cap.history = cap.history.filter(
350
427
  (h) => new Date(h.timestamp).getTime() > cutoff,
351
428
  );
429
+ // Persist the prune, else the repair is lost when the process exits.
430
+ db.prepare(
431
+ `UPDATE evolution_capabilities SET history = ?, updated_at = datetime('now') WHERE id = ?`,
432
+ ).run(JSON.stringify(cap.history), cap.id);
352
433
  }
353
434
  actions.push("Pruned stale capability history entries");
354
435
  break;
@@ -359,6 +440,12 @@ export function selfRepair(db, issue) {
359
440
  if (model.accuracy < 0.6) {
360
441
  model.accuracy = 0.5;
361
442
  model.dataPoints = 0;
443
+ model.updatedAt = new Date().toISOString();
444
+ // Persist the reset, else the repair is lost when the process exits
445
+ // (the DB row keeps the degraded accuracy across invocations).
446
+ db.prepare(
447
+ `UPDATE evolution_models SET accuracy = ?, data_points = ?, updated_at = datetime('now') WHERE id = ?`,
448
+ ).run(model.accuracy, model.dataPoints, model.id);
362
449
  actions.push(`Reset model ${model.id} for retraining`);
363
450
  }
364
451
  }
@@ -400,6 +487,7 @@ export function selfRepair(db, issue) {
400
487
  */
401
488
  export function predictBehavior(db, userId, options = {}) {
402
489
  ensureEvolutionTables(db);
490
+ loadFromDb(db);
403
491
 
404
492
  // Build predictions from capability patterns and growth log
405
493
  const recentEvents = growthLog.slice(-50);
@@ -431,6 +519,7 @@ export function predictBehavior(db, userId, options = {}) {
431
519
  */
432
520
  export function getGrowthLog(db, options = {}) {
433
521
  ensureEvolutionTables(db);
522
+ loadFromDb(db);
434
523
 
435
524
  let entries = [...growthLog];
436
525
 
@@ -449,6 +538,7 @@ export function getGrowthLog(db, options = {}) {
449
538
  */
450
539
  export function getCapabilities(db) {
451
540
  ensureEvolutionTables(db);
541
+ loadFromDb(db);
452
542
 
453
543
  return [...capabilities.values()].map((c) => ({
454
544
  id: c.id,
@@ -465,6 +555,7 @@ export function getCapabilities(db) {
465
555
  */
466
556
  export function getModels(db) {
467
557
  ensureEvolutionTables(db);
558
+ loadFromDb(db);
468
559
 
469
560
  return [...models.values()].map((m) => ({
470
561
  id: m.id,
@@ -480,6 +571,7 @@ export function getModels(db) {
480
571
  */
481
572
  export function exportModel(db, modelId) {
482
573
  ensureEvolutionTables(db);
574
+ loadFromDb(db);
483
575
 
484
576
  const model = models.get(modelId);
485
577
  if (!model) {
@@ -47,6 +47,61 @@ export function ensureEvoMapFederationTables(db) {
47
47
  `);
48
48
  }
49
49
 
50
+ /**
51
+ * Hydrate the in-memory _hubs/_lineage Maps from the DB. The CLI is one-shot:
52
+ * both start empty each process. Writes dual-write (Map + INSERT) but every read
53
+ * (listFederatedHubs/getPressureReport/getLineage/listHubsV2/buildFederationContext/
54
+ * getFederationStatsV2) is Map-only, and syncGenes/setHubStatus look up _hubs —
55
+ * so persisted hubs/lineage were invisible and sync/status-change threw
56
+ * "Hub not found". Call after ensureEvoMapFederationTables(db).
57
+ */
58
+ export function loadFromDb(db) {
59
+ if (!db) return 0;
60
+ ensureEvoMapFederationTables(db);
61
+ _hubs.clear();
62
+ _lineage.clear();
63
+
64
+ for (const r of db
65
+ .prepare(
66
+ `SELECT id, hub_url, hub_name, status, region, gene_count, last_sync, trust_score, created_at
67
+ FROM evomap_hub_federation`,
68
+ )
69
+ .all()) {
70
+ _hubs.set(r.id, {
71
+ id: r.id,
72
+ hubUrl: r.hub_url,
73
+ hubName: r.hub_name,
74
+ status: r.status,
75
+ region: r.region,
76
+ geneCount: Number(r.gene_count) || 0,
77
+ lastSync: r.last_sync,
78
+ trustScore: Number(r.trust_score) || 0,
79
+ createdAt: r.created_at,
80
+ });
81
+ }
82
+
83
+ for (const r of db
84
+ .prepare(
85
+ `SELECT id, gene_id, parent_gene_id, hub_id, generation, fitness_score, mutation_type, recombination_source, created_at
86
+ FROM gene_lineage`,
87
+ )
88
+ .all()) {
89
+ _lineage.set(r.id, {
90
+ id: r.id,
91
+ geneId: r.gene_id,
92
+ parentGeneId: r.parent_gene_id,
93
+ hubId: r.hub_id,
94
+ generation: Number(r.generation) || 0,
95
+ fitnessScore: Number(r.fitness_score) || 0,
96
+ mutationType: r.mutation_type,
97
+ recombinationSource: r.recombination_source,
98
+ createdAt: r.created_at,
99
+ });
100
+ }
101
+
102
+ return _hubs.size + _lineage.size;
103
+ }
104
+
50
105
  /* ── Hub Management ────────────────────────────────────────── */
51
106
 
52
107
  export function listFederatedHubs(db, filter = {}) {
@@ -51,6 +51,100 @@ export function ensureEvoMapGovernanceTables(db) {
51
51
  `);
52
52
  }
53
53
 
54
+ /**
55
+ * Hydrate the in-memory _ownerships/_proposals Maps from the DB. The CLI is
56
+ * one-shot: both start empty each process. Writes dual-write (Map + INSERT) but
57
+ * every read (traceOwnership/getGovernanceDashboard/listProposalsV2/
58
+ * getGovernanceStatsV2) is Map-only and voteOnGovernanceProposal/castVoteV2/
59
+ * setProposalStatus look up _proposals — so persisted ownerships/proposals were
60
+ * invisible and voting threw "Proposal not found". Call after
61
+ * ensureEvoMapGovernanceTables(db).
62
+ *
63
+ * Note: the proposals table stores only the legacy columns; V2-only fields
64
+ * (abstain/weight tallies, custom quorum/threshold) are not persisted, so they
65
+ * default here (0 / quorum 3 / threshold 0.5) to keep V2 reads and votes
66
+ * non-crashing. votesFor/votesAgainst/status ARE faithfully restored.
67
+ */
68
+ export function loadFromDb(db) {
69
+ if (!db) return 0;
70
+ ensureEvoMapGovernanceTables(db);
71
+ _ownerships.clear();
72
+ _proposals.clear();
73
+
74
+ for (const r of db
75
+ .prepare(
76
+ `SELECT id, gene_id, owner_did, originality_proof, derivation_chain, revenue_split, verified, plagiarism_score, created_at
77
+ FROM gene_ownership`,
78
+ )
79
+ .all()) {
80
+ // One corrupt JSON cell must not crash the whole load.
81
+ let originalityProof = null;
82
+ let derivationChain = [];
83
+ let revenueSplit = {};
84
+ try {
85
+ originalityProof = r.originality_proof
86
+ ? JSON.parse(r.originality_proof)
87
+ : null;
88
+ } catch {
89
+ originalityProof = null;
90
+ }
91
+ try {
92
+ derivationChain = r.derivation_chain
93
+ ? JSON.parse(r.derivation_chain)
94
+ : [];
95
+ } catch {
96
+ derivationChain = [];
97
+ }
98
+ try {
99
+ revenueSplit = r.revenue_split ? JSON.parse(r.revenue_split) : {};
100
+ } catch {
101
+ revenueSplit = {};
102
+ }
103
+ _ownerships.set(r.id, {
104
+ id: r.id,
105
+ geneId: r.gene_id,
106
+ ownerDid: r.owner_did,
107
+ originalityProof,
108
+ derivationChain,
109
+ revenueSplit,
110
+ verified: r.verified,
111
+ plagiarismScore: Number(r.plagiarism_score) || 0,
112
+ createdAt: r.created_at,
113
+ });
114
+ }
115
+
116
+ for (const r of db
117
+ .prepare(
118
+ `SELECT id, title, description, proposer_did, type, status, votes_for, votes_against, quorum_reached, voting_deadline, executed_at, created_at
119
+ FROM evomap_governance_proposals`,
120
+ )
121
+ .all()) {
122
+ _proposals.set(r.id, {
123
+ id: r.id,
124
+ title: r.title,
125
+ description: r.description || "",
126
+ proposerDid: r.proposer_did,
127
+ type: r.type,
128
+ status: r.status,
129
+ votesFor: Number(r.votes_for) || 0,
130
+ votesAgainst: Number(r.votes_against) || 0,
131
+ quorumReached: !!r.quorum_reached,
132
+ votingDeadline: r.voting_deadline,
133
+ executedAt: r.executed_at,
134
+ createdAt: r.created_at,
135
+ // Non-persisted V2 fields — default to stay NaN-safe (see fn doc).
136
+ votesAbstain: 0,
137
+ weightFor: 0,
138
+ weightAgainst: 0,
139
+ weightAbstain: 0,
140
+ quorum: 3,
141
+ threshold: 0.5,
142
+ });
143
+ }
144
+
145
+ return _ownerships.size + _proposals.size;
146
+ }
147
+
54
148
  /* ── Ownership Registration ───────────────────────────────── */
55
149
 
56
150
  export function registerOwnership(db, geneId, ownerDid, opts = {}) {
@@ -21,6 +21,19 @@ export function reportFatal(
21
21
  env = process.env,
22
22
  } = {},
23
23
  ) {
24
+ // Ctrl-C / Esc on an interactive @inquirer prompt throws ExitPromptError.
25
+ // That's a normal user cancel, not a failure — printing `error: User force
26
+ // closed the prompt...` + a non-descript exit is confusing. Treat it as a
27
+ // clean cancel: a brief note to stderr and the conventional SIGINT exit code
28
+ // (130 = 128 + SIGINT), so scripts can tell "cancelled" from "succeeded".
29
+ if (
30
+ err &&
31
+ (err.name === "ExitPromptError" || err.code === "ERR_USE_AFTER_CLOSE")
32
+ ) {
33
+ stderr.write("\nCancelled.\n");
34
+ exit(130);
35
+ return;
36
+ }
24
37
  const verbose =
25
38
  argv.includes("--verbose") || Boolean(env.CC_DEBUG) || Boolean(env.DEBUG);
26
39
  if (verbose && err && err.stack) {
@@ -38,7 +51,10 @@ export function reportFatal(
38
51
  * this only swaps the ugly default stack for the friendly boundary — it is not
39
52
  * a behavior change (still exits non-zero).
40
53
  */
41
- export function installGlobalErrorHandlers(proc = process, report = reportFatal) {
54
+ export function installGlobalErrorHandlers(
55
+ proc = process,
56
+ report = reportFatal,
57
+ ) {
42
58
  proc.on("unhandledRejection", (reason) =>
43
59
  report(reason instanceof Error ? reason : new Error(String(reason))),
44
60
  );
@@ -67,6 +67,79 @@ export function ensureHardeningTables(db) {
67
67
  `);
68
68
  }
69
69
 
70
+ /**
71
+ * Rehydrate _baselines/_audits from the persisted performance_baselines/
72
+ * hardening_audits tables. The `cc` CLI runs every command in a fresh process,
73
+ * so without this the Maps start empty and a baseline/audit collected in a
74
+ * prior invocation is invisible (`cc hardening baseline list`/`audit reports`
75
+ * show nothing; `baseline compare`/`audit report <id>` throw "not found"; and —
76
+ * most damagingly — `cc hardening deploy-check` reports "No baseline / No audit"
77
+ * and yields a silently-wrong go/no-go verdict even when the rows exist). Call
78
+ * after ensureHardeningTables(db).
79
+ */
80
+ export function loadFromDb(db) {
81
+ if (!db) return 0;
82
+ _baselines.clear();
83
+ _audits.clear();
84
+
85
+ const baselineRows = db.prepare(`SELECT * FROM performance_baselines`).all();
86
+ for (const row of baselineRows) {
87
+ let metrics = {};
88
+ let environment = {};
89
+ try {
90
+ metrics = row.metrics ? JSON.parse(row.metrics) : {};
91
+ } catch {
92
+ metrics = {};
93
+ }
94
+ try {
95
+ environment = row.environment ? JSON.parse(row.environment) : {};
96
+ } catch {
97
+ environment = {};
98
+ }
99
+ _baselines.set(row.id, {
100
+ id: row.id,
101
+ name: row.name,
102
+ version: row.version,
103
+ status: row.status,
104
+ metrics,
105
+ environment,
106
+ sampleCount: row.sample_count ?? 0,
107
+ createdAt: row.created_at ?? null,
108
+ completedAt: row.completed_at ?? null,
109
+ });
110
+ }
111
+
112
+ const auditRows = db.prepare(`SELECT * FROM hardening_audits`).all();
113
+ for (const row of auditRows) {
114
+ let checks = [];
115
+ let recommendations = [];
116
+ try {
117
+ checks = row.checks ? JSON.parse(row.checks) : [];
118
+ } catch {
119
+ checks = [];
120
+ }
121
+ try {
122
+ recommendations = row.recommendations
123
+ ? JSON.parse(row.recommendations)
124
+ : [];
125
+ } catch {
126
+ recommendations = [];
127
+ }
128
+ _audits.set(row.id, {
129
+ id: row.id,
130
+ name: row.name,
131
+ checks,
132
+ passed: row.passed ?? 0,
133
+ failed: row.failed ?? 0,
134
+ score: row.score ?? 0,
135
+ recommendations,
136
+ createdAt: row.created_at ?? null,
137
+ });
138
+ }
139
+
140
+ return _baselines.size + _audits.size;
141
+ }
142
+
70
143
  /* ── Baseline Collection ──────────────────────────────────── */
71
144
 
72
145
  export function collectBaseline(db, name, version) {
@@ -5,6 +5,8 @@
5
5
  * with Ebbinghaus forgetting curve and spacing effect reinforcement.
6
6
  */
7
7
 
8
+ import { escapeLike } from "./sql-like.js";
9
+
8
10
  // ─── Configuration ───────────────────────────────────────────────
9
11
  export const MEMORY_CONFIG = {
10
12
  workingCapacity: 50,
@@ -292,8 +294,10 @@ export function recallMemory(db, query, options = {}) {
292
294
  // Search long-term memory (DB)
293
295
  ensureMemoryTables(db);
294
296
  const ltRows = db
295
- .prepare(`SELECT * FROM memory_long_term WHERE content LIKE ? LIMIT ?`)
296
- .all(`%${query}%`, limit);
297
+ .prepare(
298
+ `SELECT * FROM memory_long_term WHERE content LIKE ? ESCAPE '\\' LIMIT ?`,
299
+ )
300
+ .all(`%${escapeLike(query)}%`, limit);
297
301
  for (const row of ltRows) {
298
302
  const retention = calcRetention(row.last_accessed);
299
303
  if (retention >= MEMORY_CONFIG.recallThreshold) {
@@ -316,8 +320,10 @@ export function recallMemory(db, query, options = {}) {
316
320
 
317
321
  // Search core memory (DB) — core memories don't decay
318
322
  const coreRows = db
319
- .prepare(`SELECT * FROM memory_core WHERE content LIKE ? LIMIT ?`)
320
- .all(`%${query}%`, limit);
323
+ .prepare(
324
+ `SELECT * FROM memory_core WHERE content LIKE ? ESCAPE '\\' LIMIT ?`,
325
+ )
326
+ .all(`%${escapeLike(query)}%`, limit);
321
327
  for (const row of coreRows) {
322
328
  db.prepare(
323
329
  `UPDATE memory_core SET access_count = access_count + 1, last_accessed = ? WHERE id = ?`,
@@ -444,9 +450,9 @@ function _searchByType(db, query, type, options = {}) {
444
450
  ensureMemoryTables(db);
445
451
  const ltRows = db
446
452
  .prepare(
447
- `SELECT * FROM memory_long_term WHERE type = ? AND content LIKE ? LIMIT ?`,
453
+ `SELECT * FROM memory_long_term WHERE type = ? AND content LIKE ? ESCAPE '\\' LIMIT ?`,
448
454
  )
449
- .all(type, `%${query}%`, limit);
455
+ .all(type, `%${escapeLike(query)}%`, limit);
450
456
  for (const row of ltRows) {
451
457
  results.push({
452
458
  id: row.id,
@@ -462,9 +468,9 @@ function _searchByType(db, query, type, options = {}) {
462
468
 
463
469
  const coreRows = db
464
470
  .prepare(
465
- `SELECT * FROM memory_core WHERE type = ? AND content LIKE ? LIMIT ?`,
471
+ `SELECT * FROM memory_core WHERE type = ? AND content LIKE ? ESCAPE '\\' LIMIT ?`,
466
472
  )
467
- .all(type, `%${query}%`, limit);
473
+ .all(type, `%${escapeLike(query)}%`, limit);
468
474
  for (const row of coreRows) {
469
475
  results.push({
470
476
  id: row.id,
@@ -78,7 +78,10 @@ export function sanitizeFilename(name) {
78
78
  * Convert a note to markdown with YAML frontmatter.
79
79
  */
80
80
  export function noteToMarkdown(note) {
81
- const tags = JSON.parse(note.tags || "[]");
81
+ // safeJsonParse (not bare JSON.parse): exportToMarkdown loops over every note,
82
+ // so one corrupt/hand-edited `tags` cell would otherwise throw and abort the
83
+ // ENTIRE export mid-way. Matches generateIndexHtml, which already guards.
84
+ const tags = safeJsonParse(note.tags, []);
82
85
  const lines = [
83
86
  "---",
84
87
  `title: "${note.title.replace(/"/g, '\\"')}"`,
@@ -136,7 +139,10 @@ export function exportToMarkdown(db, outputDir, options = {}) {
136
139
  * Generate a minimal HTML page for a note.
137
140
  */
138
141
  export function noteToHtml(note) {
139
- const tags = JSON.parse(note.tags || "[]");
142
+ // safeJsonParse (not bare JSON.parse): exportToSite loops over every note, so
143
+ // one corrupt `tags` cell would otherwise throw and abort the whole site
144
+ // export — after index.html was already written, leaving dangling links.
145
+ const tags = safeJsonParse(note.tags, []);
140
146
  const tagsHtml = tags
141
147
  .map((t) => `<span class="tag">${escapeHtml(t)}</span>`)
142
148
  .join(" ");
@@ -95,6 +95,85 @@ export function ensureKnowledgeGraphTables(db) {
95
95
  );
96
96
  }
97
97
 
98
+ /**
99
+ * Hydrate the in-memory graph from the DB. The CLI is one-shot: _entities/
100
+ * _relations/_outEdges/_inEdges start empty every process. Writes dual-write
101
+ * (Map + INSERT), but every read is Map-only and nothing ever SELECTed the
102
+ * tables back — so persisted entities/relations were invisible on the next
103
+ * invocation (list/show/stats/export empty; add-relation threw "Source entity
104
+ * not found"; remove returned false and left the row). Call after
105
+ * ensureKnowledgeGraphTables(db).
106
+ */
107
+ export function loadFromDb(db) {
108
+ if (!db) return 0;
109
+ ensureKnowledgeGraphTables(db);
110
+ _entities.clear();
111
+ _relations.clear();
112
+ _outEdges.clear();
113
+ _inEdges.clear();
114
+
115
+ const entityRows = db
116
+ .prepare(
117
+ `SELECT id, name, type, properties, tags, created_at, updated_at
118
+ FROM kg_entities ORDER BY created_at ASC`,
119
+ )
120
+ .all();
121
+ for (const r of entityRows) {
122
+ // A single corrupt properties/tags cell must not crash the whole load.
123
+ let properties = null;
124
+ let tags = null;
125
+ try {
126
+ properties = r.properties ? JSON.parse(r.properties) : null;
127
+ } catch {
128
+ properties = null;
129
+ }
130
+ try {
131
+ tags = r.tags ? JSON.parse(r.tags) : null;
132
+ } catch {
133
+ tags = null;
134
+ }
135
+ _entities.set(r.id, {
136
+ id: r.id,
137
+ name: r.name,
138
+ type: r.type,
139
+ properties,
140
+ tags,
141
+ createdAt: Number(r.created_at),
142
+ updatedAt: Number(r.updated_at),
143
+ _seq: ++_seq,
144
+ });
145
+ }
146
+
147
+ const relationRows = db
148
+ .prepare(
149
+ `SELECT id, source_id, target_id, relation_type, weight, properties, created_at
150
+ FROM kg_relationships ORDER BY created_at ASC`,
151
+ )
152
+ .all();
153
+ for (const r of relationRows) {
154
+ let properties = null;
155
+ try {
156
+ properties = r.properties ? JSON.parse(r.properties) : null;
157
+ } catch {
158
+ properties = null;
159
+ }
160
+ const relation = {
161
+ id: r.id,
162
+ sourceId: r.source_id,
163
+ targetId: r.target_id,
164
+ relationType: r.relation_type,
165
+ weight: Number(r.weight),
166
+ properties,
167
+ createdAt: Number(r.created_at),
168
+ _seq: ++_seq,
169
+ };
170
+ _relations.set(r.id, relation);
171
+ _indexRelation(relation);
172
+ }
173
+
174
+ return _entities.size + _relations.size;
175
+ }
176
+
98
177
  /* ── Catalogs ──────────────────────────────────────────────── */
99
178
 
100
179
  export function listEntityTypes() {
@@ -292,20 +292,29 @@ export class LLMProviderRegistry {
292
292
  if (!this.providers.has(name)) {
293
293
  throw new Error(`Provider "${name}" not found`);
294
294
  }
295
- // Reset all
296
- this.db.prepare("UPDATE llm_providers SET is_active = 0 WHERE 1=1").run();
297
- // Set active
298
- this.db
299
- .prepare(
300
- "INSERT OR REPLACE INTO llm_providers (name, display_name, base_url, api_key_env, models, is_active) VALUES (?, ?, ?, ?, ?, 1)",
301
- )
302
- .run(
303
- name,
304
- this.providers.get(name).displayName,
305
- this.providers.get(name).baseUrl,
306
- this.providers.get(name).apiKeyEnv,
307
- JSON.stringify(this.providers.get(name).models),
308
- );
295
+ // Clear every active flag then mark the new provider active atomically.
296
+ // Without a transaction, a failure on the second statement leaves NO
297
+ // provider active — which getActive() silently masks as the "ollama"
298
+ // fallback, so a failed switch would quietly lose the current provider.
299
+ const applyWrites = () => {
300
+ this.db.prepare("UPDATE llm_providers SET is_active = 0 WHERE 1=1").run();
301
+ this.db
302
+ .prepare(
303
+ "INSERT OR REPLACE INTO llm_providers (name, display_name, base_url, api_key_env, models, is_active) VALUES (?, ?, ?, ?, ?, 1)",
304
+ )
305
+ .run(
306
+ name,
307
+ this.providers.get(name).displayName,
308
+ this.providers.get(name).baseUrl,
309
+ this.providers.get(name).apiKeyEnv,
310
+ JSON.stringify(this.providers.get(name).models),
311
+ );
312
+ };
313
+ if (this.db && typeof this.db.transaction === "function") {
314
+ this.db.transaction(applyWrites)();
315
+ } else {
316
+ applyWrites();
317
+ }
309
318
  return this.providers.get(name);
310
319
  }
311
320