chainlesschain 0.162.148 → 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 (322) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/assets/web-panel/.build-hash +1 -1
  4. package/src/assets/web-panel/assets/{AIOps-DwpCCp64.js → AIOps-CBLvrjeG.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-C9pBYocA.js → ActionButton-DYv2GtE0.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-BWAkeXxK.js → Analytics-CL6PZ-Ww.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-CivFGH6B.js → AppLayout-xuyHt4uA.js} +3 -3
  8. package/src/assets/web-panel/assets/{Audit-Cm8hRpZm.js → Audit-DOvSVycq.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-DXdFMsE8.js → Backup-DMhfTswr.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-uAwSTeql.js → BaseInput-CQxDdm63.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-KU8eeJJE.js → Chat-BEeNhK2a.js} +5 -5
  12. package/src/assets/web-panel/assets/ChatBubbleRenderer-8nul8eTq.js +1 -0
  13. package/src/assets/web-panel/assets/{Checkbox-C6AMDkjd.js → Checkbox-CL04O-ER.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-t2moDxcO.js → Codegen-C50o-n7x.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-DCcsRRhN.js → Col-CH-bDkzs.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-DtB-8SAC.js → Community-DqAIMvSe.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-CZm8THYA.js → Compact-C43fo_my.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-LiQgC7g1.js → Compliance-BERnMrdP.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-CA8SAxht.js → Cowork-Baw3w1gp.js} +4 -4
  20. package/src/assets/web-panel/assets/{Cron-CtRaF1wD.js → Cron-BEqAHF1-.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-6-br6Hub.js → Crosschain-CvnmKwK4.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-Do2EccrL.js → DID-iMPxgVdt.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-wrXcbzGe.js → Dashboard--4SJX3YR.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-p3FsT245.js → Dropdown-BgLV6xgz.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-D95A2L8q.js → EmailListRenderer-Bvb8oUD8.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-cLuJW2zo.js → FamilyGuardDashboard-DpXPjJB5.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-Brgq_cbN.js → Federation-BbFfJ1Xi.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-DWLCkNgh.js → FormItemContext-DeGq1B-q.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-BBqUfQd6.js → GenericCardRenderer-CNW7s9zM.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-8F090w4I.js → Git-L1PjW-lT.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-CCogEbxb.js → Governance-PK-X58to.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-CfLD7v7C.js → Inference-BePWEH-d.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-DDuHJewd.js → KnowledgeGraph-LF_sBvdL.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-CE8KSEVC.js → Logs-BKkfk9hy.js} +2 -2
  35. package/src/assets/web-panel/assets/{Marketplace-DmwpZmhT.js → Marketplace-BNMqUDla.js} +1 -1
  36. package/src/assets/web-panel/assets/{McpTools-Bf7AazU8.js → McpTools-w4WPiyz2.js} +5 -5
  37. package/src/assets/web-panel/assets/{Memory-D0QU_00S.js → Memory-DUKMVGNi.js} +2 -2
  38. package/src/assets/web-panel/assets/{MobileBridge-yXS9xdhx.js → MobileBridge-BWhiEyTJ.js} +1 -1
  39. package/src/assets/web-panel/assets/{MobileProjects-BuDUoGUP.js → MobileProjects-Ocf5JEkX.js} +1 -1
  40. package/src/assets/web-panel/assets/{Mtc-BYyHy28p.js → Mtc-D2B6MMhU.js} +4 -4
  41. package/src/assets/web-panel/assets/{MtcAudit-CK0aqpiZ.js → MtcAudit-DdYjCq1O.js} +4 -4
  42. package/src/assets/web-panel/assets/{Multisig-mNimKYeb.js → Multisig-Cb1hfuUZ.js} +3 -3
  43. package/src/assets/web-panel/assets/{NLProgramming-AioAJ0YA.js → NLProgramming-CTeImGp7.js} +1 -1
  44. package/src/assets/web-panel/assets/{Notes-CVVNCLHE.js → Notes-BjYNc7eQ.js} +4 -4
  45. package/src/assets/web-panel/assets/{NotificationSettings-C4ABj-TK.js → NotificationSettings-Dn_NtRXQ.js} +1 -1
  46. package/src/assets/web-panel/assets/{OrderTableRenderer-DIp8Xcbd.js → OrderTableRenderer-DVYYIizh.js} +1 -1
  47. package/src/assets/web-panel/assets/{Organization-uozl_gWK.js → Organization-Be2Kmr5j.js} +4 -4
  48. package/src/assets/web-panel/assets/{Overflow-BCZOM2hK.js → Overflow-Cu_-qRlR.js} +1 -1
  49. package/src/assets/web-panel/assets/{P2P-CArcaiaj.js → P2P-DD2HoGzE.js} +2 -2
  50. package/src/assets/web-panel/assets/{PdhVaultBrowser-Sgq2Srr8.js → PdhVaultBrowser-BRI7DVth.js} +3 -3
  51. package/src/assets/web-panel/assets/{Permissions-BYrQrXnH.js → Permissions-C9Srcs2M.js} +4 -4
  52. package/src/assets/web-panel/assets/{PersonalDataHub-BzHStAbz.js → PersonalDataHub-CUqcMgo1.js} +3 -3
  53. package/src/assets/web-panel/assets/{Pipeline-k7KqxX1M.js → Pipeline-HBrQGLXt.js} +1 -1
  54. package/src/assets/web-panel/assets/{Privacy-IumTUWqx.js → Privacy-D-B0vjwh.js} +1 -1
  55. package/src/assets/web-panel/assets/{ProjectInit-BRyImYTf.js → ProjectInit-eTeLIu9e.js} +2 -2
  56. package/src/assets/web-panel/assets/{ProjectSettings-BFIqTBFk.js → ProjectSettings-DrRqCsC6.js} +2 -2
  57. package/src/assets/web-panel/assets/{Projects-Dpid9CDg.js → Projects-1G9DNOhI.js} +1 -1
  58. package/src/assets/web-panel/assets/{Providers-CyyFnUPs.js → Providers-RkTZzpxP.js} +1 -1
  59. package/src/assets/web-panel/assets/{QrScannerModal-C82cRx-X.js → QrScannerModal-BSCUgsgC.js} +1 -1
  60. package/src/assets/web-panel/assets/{QuickAsk-DGxDF521.js → QuickAsk-CHgyM3Bz.js} +1 -1
  61. package/src/assets/web-panel/assets/{Recommend-Cns-Am1y.js → Recommend-0lry4OZq.js} +1 -1
  62. package/src/assets/web-panel/assets/{RemoteSession-R7OqAIlg.js → RemoteSession-Cn45UroZ.js} +2 -2
  63. package/src/assets/web-panel/assets/{Reputation-D7mgPIYV.js → Reputation-Q-Zjb707.js} +1 -1
  64. package/src/assets/web-panel/assets/{Row-B3lEURyd.js → Row-BdM70oda.js} +1 -1
  65. package/src/assets/web-panel/assets/{RssFeed-9_UVrpBt.js → RssFeed-DmOAKKap.js} +2 -2
  66. package/src/assets/web-panel/assets/{Search-ClZeO80q.js → Search-Dwavbm07.js} +1 -1
  67. package/src/assets/web-panel/assets/{Security-BNNJczEp.js → Security-DukXFCnk.js} +3 -3
  68. package/src/assets/web-panel/assets/{Services-C5SjrWUj.js → Services-BIlRnITu.js} +2 -2
  69. package/src/assets/web-panel/assets/{Skeleton-Ci_obQ-g.js → Skeleton-YYVQdhhQ.js} +1 -1
  70. package/src/assets/web-panel/assets/{Skills-DdebN15P.js → Skills-B8_iYHz2.js} +1 -1
  71. package/src/assets/web-panel/assets/{Sla-OinZP2vi.js → Sla-BdVrhT31.js} +1 -1
  72. package/src/assets/web-panel/assets/{SpeechSettings-CxzbNF51.js → SpeechSettings-CD3ggRx7.js} +1 -1
  73. package/src/assets/web-panel/assets/{SyncSettings-D06N_66b.js → SyncSettings-Bp02VZFH.js} +2 -2
  74. package/src/assets/web-panel/assets/{Tasks-BdEdW0AZ.js → Tasks-DEVmCEsr.js} +1 -1
  75. package/src/assets/web-panel/assets/{Templates-F1ctKmPa.js → Templates-B6czWc4N.js} +1 -1
  76. package/src/assets/web-panel/assets/{Tenant-CVz1Urot.js → Tenant-BCJLv17r.js} +1 -1
  77. package/src/assets/web-panel/assets/Terminal-CD132d2Y.js +3 -0
  78. package/src/assets/web-panel/assets/{TimelineRenderer-Doitzjmf.js → TimelineRenderer-ZB-CvkZl.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tokens-BpyVRpVA.js → Tokens-BnSY0S-s.js} +1 -1
  80. package/src/assets/web-panel/assets/{Trigger-nWhWYTbU.js → Trigger-VZw9Oy2w.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trust-DK_G-wLx.js → Trust-pZq7Hjd2.js} +1 -1
  82. package/src/assets/web-panel/assets/{UkeySign-B5yBUojO.js → UkeySign-DnQaqk4q.js} +1 -1
  83. package/src/assets/web-panel/assets/{VideoEditing-C5D51qAe.js → VideoEditing-BEUfmvJV.js} +1 -1
  84. package/src/assets/web-panel/assets/{Wallet-CLbL9K7v.js → Wallet-CoZKMXJ2.js} +4 -4
  85. package/src/assets/web-panel/assets/{WebAuthn-DZUelI3V.js → WebAuthn-CBOGVx1I.js} +5 -5
  86. package/src/assets/web-panel/assets/{WorkflowEditor-8RPxt4KW.js → WorkflowEditor-huSKn7TT.js} +1 -1
  87. package/src/assets/web-panel/assets/{chat-4N4tOA3d.js → chat-A_3w6FBO.js} +1 -1
  88. package/src/assets/web-panel/assets/{colors-zbbGVrua.js → colors-D1Bem9Oy.js} +1 -1
  89. package/src/assets/web-panel/assets/{compact-item-D7iMkbnE.js → compact-item-CJYJj0oO.js} +1 -1
  90. package/src/assets/web-panel/assets/{createContext-CBzPJv-w.js → createContext-BkbFiKT4.js} +1 -1
  91. package/src/assets/web-panel/assets/devWarning-WDr3_M_N.js +1 -0
  92. package/src/assets/web-panel/assets/{hasIn-bHdrQSqZ.js → hasIn-CKvUafVY.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-DbE5D0WL.js → index-AjrSPnvv.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-BCr0geV9.js → index-B8i0lViZ.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-CiG1IZao.js → index-B9Svn0zc.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-B1s0Bz9O.js → index-BHdHSX06.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-QFObYeo1.js → index-BHdailyo.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BnBOpqv3.js → index-BJwlEnYo.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CdmMoYN1.js → index-BOoAQjJz.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DUyjUkY7.js → index-BSgWxAOG.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CqdPyWm5.js → index-BdutMsne.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DmqlJed-.js → index-BiDWxzbn.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-S74FpAIn.js → index-By5a0T_W.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-kmh1TxRa.js → index-C-WIY-FQ.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BTIjjXry.js → index-C37f6iey.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-BS4_Mwk6.js → index-C9bWmTcO.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BBNr77E1.js → index-CBaosWRO.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-QNAG4JtR.js → index-CBlBVJ_m.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Bqmx24kh.js → index-CD62EEGo.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CQfu1U78.js → index-CUj-l7GM.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BJ4ZGyW0.js → index-CVS8Ymuq.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-Ci009ijp.js → index-ChkXUj3f.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-oDKNgCsP.js → index-Cj0OZ-37.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-BZb8F8YG.js → index-Co3OFL0t.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-308gCGh7.js → index-Crp8CbRg.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CPxkoKgA.js → index-D22zNXiS.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-xYCm6W2h.js → index-DTs_D1OL.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BtbbdLnf.js → index-DfgCdFrN.js} +3 -3
  119. package/src/assets/web-panel/assets/{index-BsKehmmS.js → index-DjYrecNb.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CkxK86vf.js → index-DpW9cf3e.js} +1 -1
  121. package/src/assets/web-panel/assets/index-Dwix3p4g.js +1 -0
  122. package/src/assets/web-panel/assets/{index-CvRMA9uT.js → index-F--HuPG1.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DE9j5YgT.js → index-Fuk6t_3K.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-B7b1hGry.js → index-JEAGMii9.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-D1YDh7Wr.js → index-PF-mpv8K.js} +1 -1
  126. package/src/assets/web-panel/assets/index-SHaoZ0CA.js +1 -0
  127. package/src/assets/web-panel/assets/{index-CQ6NcfWz.js → index-b-sbVdjQ.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-DyoNgbXl.js → index-pyvMVX8r.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DISWAYce.js → index-qNTtOVi_.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-D4XKpj6c.js → index-tgO8iza6.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-CahryTX0.js → index-ttDQVhZy.js} +1 -1
  132. package/src/assets/web-panel/assets/{initDefaultProps-BD55yNBt.js → initDefaultProps-DtrnfsZH.js} +1 -1
  133. package/src/assets/web-panel/assets/{motion-B5Bbe77U.js → motion-D4zqSaX3.js} +1 -1
  134. package/src/assets/web-panel/assets/{move-CTvIqHEH.js → move-CGFGOUQj.js} +1 -1
  135. package/src/assets/web-panel/assets/{mtc-parser-BkNyPQKB.js → mtc-parser-DH2HvkJl.js} +1 -1
  136. package/src/assets/web-panel/assets/{omit-BaXJXgHA.js → omit-jJ2at5HX.js} +1 -1
  137. package/src/assets/web-panel/assets/{pickAttrs-Bw6-YTxH.js → pickAttrs-CRyMT1Fv.js} +1 -1
  138. package/src/assets/web-panel/assets/{placementArrow-BLdbkLqJ.js → placementArrow-DZ_CX0Pt.js} +1 -1
  139. package/src/assets/web-panel/assets/{responsiveObserve-IVYkzntU.js → responsiveObserve-wruHk-h5.js} +1 -1
  140. package/src/assets/web-panel/assets/{slide-DFMFwwtY.js → slide-BGgx8q67.js} +1 -1
  141. package/src/assets/web-panel/assets/{statusUtils-CURYRtZ1.js → statusUtils-Do5M7gKm.js} +1 -1
  142. package/src/assets/web-panel/assets/{styleChecker-Cfz63s1r.js → styleChecker-CRa-GZpX.js} +1 -1
  143. package/src/assets/web-panel/assets/{useFlexGapSupport-COJL0KE3.js → useFlexGapSupport-BxPcq6pj.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFs-YLLojQQf.js → useFs-v5O2ZcJm.js} +1 -1
  145. package/src/assets/web-panel/assets/{usePersonalDataHub-BF_21qUC.js → usePersonalDataHub--z2FU0Px.js} +1 -1
  146. package/src/assets/web-panel/assets/{vnode-9ZpkA7bb.js → vnode-1emidVKd.js} +1 -1
  147. package/src/assets/web-panel/assets/{zoom-DhtAfhl8.js → zoom-CcJaRyHs.js} +1 -1
  148. package/src/assets/web-panel/index.html +1 -1
  149. package/src/assets/web-panel/remote-session-sw.js +43 -0
  150. package/src/command-manifest.json +22 -1
  151. package/src/commands/a2a.js +19 -4
  152. package/src/commands/activitypub.js +20 -3
  153. package/src/commands/agent.js +71 -10
  154. package/src/commands/audit.js +40 -24
  155. package/src/commands/codeintel.js +320 -0
  156. package/src/commands/collab.js +15 -2
  157. package/src/commands/compliance.js +5 -0
  158. package/src/commands/config.js +4 -1
  159. package/src/commands/dao.js +86 -14
  160. package/src/commands/dev.js +2 -0
  161. package/src/commands/did.js +7 -1
  162. package/src/commands/dlp.js +23 -1
  163. package/src/commands/economy.js +29 -3
  164. package/src/commands/eval.js +255 -0
  165. package/src/commands/evomap.js +26 -0
  166. package/src/commands/governance.js +17 -3
  167. package/src/commands/hardening.js +18 -0
  168. package/src/commands/incentive.js +5 -0
  169. package/src/commands/init.js +46 -2
  170. package/src/commands/kg.js +4 -0
  171. package/src/commands/loop.js +6 -1
  172. package/src/commands/lowcode.js +15 -2
  173. package/src/commands/marketplace.js +40 -6
  174. package/src/commands/matrix.js +20 -1
  175. package/src/commands/memory.js +4 -1
  176. package/src/commands/mtc.js +7 -1
  177. package/src/commands/nostr.js +31 -4
  178. package/src/commands/note.js +7 -4
  179. package/src/commands/plugin.js +474 -0
  180. package/src/commands/pqc.js +5 -0
  181. package/src/commands/reputation.js +10 -1
  182. package/src/commands/scim.js +6 -0
  183. package/src/commands/session.js +32 -10
  184. package/src/commands/siem.js +11 -0
  185. package/src/commands/sla.js +18 -3
  186. package/src/commands/social.js +38 -5
  187. package/src/commands/sso.js +10 -2
  188. package/src/commands/stress.js +23 -4
  189. package/src/commands/team.js +463 -0
  190. package/src/commands/tech.js +2 -0
  191. package/src/commands/tenant.js +10 -1
  192. package/src/commands/terraform.js +6 -0
  193. package/src/commands/update.js +1 -1
  194. package/src/commands/zkp.js +20 -0
  195. package/src/gateways/ws/message-dispatcher.js +48 -2
  196. package/src/gateways/ws/remote-session-protocol.js +140 -42
  197. package/src/gateways/ws/ws-server.js +1 -1
  198. package/src/harness/jsonl-session-store.js +12 -5
  199. package/src/harness/plugin-manager.js +16 -4
  200. package/src/harness/prompt-compressor.js +27 -1
  201. package/src/harness/remote-command-ledger.js +189 -0
  202. package/src/harness/remote-session-push-apns.js +246 -0
  203. package/src/harness/remote-session-push-errors.js +15 -0
  204. package/src/harness/remote-session-push-fcm.js +9 -25
  205. package/src/harness/remote-session-push-huawei.js +174 -0
  206. package/src/harness/remote-session-push-oppo.js +171 -0
  207. package/src/harness/remote-session-push-senders.js +42 -0
  208. package/src/harness/remote-session-push-vivo.js +179 -0
  209. package/src/harness/remote-session-push-web.js +299 -0
  210. package/src/harness/remote-session-push-xiaomi.js +99 -0
  211. package/src/harness/worktree-isolator.js +16 -6
  212. package/src/index.js +6 -0
  213. package/src/lib/__tests__/logger.test.js +5 -2
  214. package/src/lib/a2a-protocol.js +25 -1
  215. package/src/lib/activitypub-bridge.js +61 -0
  216. package/src/lib/agent-core.js +4 -0
  217. package/src/lib/agent-economy.js +262 -29
  218. package/src/lib/agent-network.js +7 -1
  219. package/src/lib/agent-sandbox.js +161 -5
  220. package/src/lib/agent-team/task-lease.js +434 -0
  221. package/src/lib/agent-team/team-budget.js +165 -0
  222. package/src/lib/agent-team/team-mailbox.js +106 -0
  223. package/src/lib/agent-team/team-runner.js +282 -0
  224. package/src/lib/agent-team/team-worktree.js +236 -0
  225. package/src/lib/agents.js +18 -0
  226. package/src/lib/async-hook-supervisor.cjs +391 -0
  227. package/src/lib/audit-logger.js +7 -6
  228. package/src/lib/autonomous-developer.js +60 -0
  229. package/src/lib/chat-core.js +17 -4
  230. package/src/lib/collaboration-governance.js +56 -0
  231. package/src/lib/community-governance.js +68 -0
  232. package/src/lib/compliance-manager.js +63 -0
  233. package/src/lib/cross-chain.js +5 -0
  234. package/src/lib/dao-governance.js +151 -2
  235. package/src/lib/did-manager.js +23 -10
  236. package/src/lib/dlp-engine.js +70 -0
  237. package/src/lib/eval/runner.js +251 -0
  238. package/src/lib/eval/tasks.js +626 -0
  239. package/src/lib/eval/trend.js +200 -0
  240. package/src/lib/evolution-system.js +92 -0
  241. package/src/lib/evomap-federation.js +55 -0
  242. package/src/lib/evomap-governance.js +94 -0
  243. package/src/lib/fatal-handler.js +17 -1
  244. package/src/lib/hardening-manager.js +73 -0
  245. package/src/lib/hierarchical-memory.js +14 -8
  246. package/src/lib/knowledge-exporter.js +8 -2
  247. package/src/lib/knowledge-graph.js +79 -0
  248. package/src/lib/llm-providers.js +23 -14
  249. package/src/lib/logger.js +4 -1
  250. package/src/lib/lsp/__tests__/benchmark.test.js +88 -0
  251. package/src/lib/lsp/__tests__/code-intelligence.integration.test.js +129 -0
  252. package/src/lib/lsp/__tests__/code-intelligence.test.js +228 -0
  253. package/src/lib/lsp/__tests__/jsonrpc-stream.test.js +104 -0
  254. package/src/lib/lsp/__tests__/lsp-client.test.js +269 -0
  255. package/src/lib/lsp/__tests__/lsp-manager.test.js +333 -0
  256. package/src/lib/lsp/__tests__/lsp-server-registry.test.js +128 -0
  257. package/src/lib/lsp/benchmark.js +257 -0
  258. package/src/lib/lsp/code-intelligence.js +356 -0
  259. package/src/lib/lsp/jsonrpc-stream.js +139 -0
  260. package/src/lib/lsp/lsp-client.js +339 -0
  261. package/src/lib/lsp/lsp-manager.js +375 -0
  262. package/src/lib/lsp/lsp-server-registry.js +196 -0
  263. package/src/lib/matrix-bridge.js +84 -0
  264. package/src/lib/memory-manager.js +5 -3
  265. package/src/lib/nostr-bridge.js +53 -0
  266. package/src/lib/permission-engine.js +22 -4
  267. package/src/lib/plugin-monitor-supervisor.js +238 -0
  268. package/src/lib/plugin-runtime/__tests__/remote-source.test.js +256 -0
  269. package/src/lib/plugin-runtime/agents.js +51 -0
  270. package/src/lib/plugin-runtime/bin.js +100 -0
  271. package/src/lib/plugin-runtime/hooks.js +100 -0
  272. package/src/lib/plugin-runtime/install.js +396 -0
  273. package/src/lib/plugin-runtime/lsp.js +75 -0
  274. package/src/lib/plugin-runtime/manifest.js +458 -0
  275. package/src/lib/plugin-runtime/mcp.js +89 -0
  276. package/src/lib/plugin-runtime/monitors.js +100 -0
  277. package/src/lib/plugin-runtime/policy.js +152 -0
  278. package/src/lib/plugin-runtime/reload.js +79 -0
  279. package/src/lib/plugin-runtime/remote-source.js +240 -0
  280. package/src/lib/plugin-runtime/scopes.js +197 -0
  281. package/src/lib/plugin-runtime/settings.js +119 -0
  282. package/src/lib/plugin-runtime/signature.js +107 -0
  283. package/src/lib/plugin-runtime/skills.js +43 -0
  284. package/src/lib/plugin-runtime/trust.js +140 -0
  285. package/src/lib/pqc-manager.js +64 -0
  286. package/src/lib/reputation-optimizer.js +101 -0
  287. package/src/lib/sandbox-egress-proxy.js +262 -0
  288. package/src/lib/sandbox-fs-policy.js +112 -0
  289. package/src/lib/sandbox-network-policy.js +151 -0
  290. package/src/lib/sandbox-v2.js +24 -18
  291. package/src/lib/scim-manager.js +36 -0
  292. package/src/lib/session-manager.js +5 -2
  293. package/src/lib/settings-hook-events.cjs +78 -6
  294. package/src/lib/settings-hooks.cjs +30 -3
  295. package/src/lib/settings-loader.cjs +35 -1
  296. package/src/lib/siem-exporter.js +45 -0
  297. package/src/lib/skill-loader.js +38 -2
  298. package/src/lib/skill-marketplace.js +83 -0
  299. package/src/lib/sla-manager.js +88 -0
  300. package/src/lib/social-manager.js +74 -0
  301. package/src/lib/stress-tester.js +65 -0
  302. package/src/lib/tech-learning-engine.js +75 -0
  303. package/src/lib/telemetry/span-recorder.js +237 -0
  304. package/src/lib/tenant-saas.js +107 -0
  305. package/src/lib/terraform-manager.js +67 -0
  306. package/src/lib/token-incentive.js +180 -29
  307. package/src/lib/wallet-manager.js +81 -35
  308. package/src/lib/zkp-engine.js +87 -0
  309. package/src/repl/agent-repl.js +417 -6
  310. package/src/runtime/__tests__/auto-pin.test.js +104 -0
  311. package/src/runtime/agent-core.js +771 -104
  312. package/src/runtime/auto-pin.js +117 -0
  313. package/src/runtime/coding-agent-contract-shared.cjs +82 -8
  314. package/src/runtime/coding-agent-policy.cjs +32 -7
  315. package/src/runtime/fallback-model.js +134 -7
  316. package/src/runtime/headless-runner.js +388 -108
  317. package/src/runtime/mcp-config.js +46 -0
  318. package/src/assets/web-panel/assets/ChatBubbleRenderer-DCNfbdlx.js +0 -1
  319. package/src/assets/web-panel/assets/Terminal-BvAK_Zel.js +0 -3
  320. package/src/assets/web-panel/assets/devWarning-C2Z5LRgq.js +0 -1
  321. package/src/assets/web-panel/assets/index-BGp6Yr-Y.js +0 -1
  322. package/src/assets/web-panel/assets/index-BXiw9dQf.js +0 -1
@@ -151,6 +151,66 @@ export function ensureAutonomousDevTables(db) {
151
151
  );
152
152
  }
153
153
 
154
+ /**
155
+ * Rehydrate _sessions/_adrs from the persisted dev_sessions/
156
+ * architecture_decisions tables. The `cc` CLI runs every command in a fresh
157
+ * process, so without this the Maps start empty and a session/ADR created in a
158
+ * prior invocation is invisible (`cc dev list`/`show`/`adrs` show nothing) and
159
+ * every mutation — recordADR, advancePhase, etc. — throws "Session not found"
160
+ * against the empty Map. Call after ensureAutonomousDevTables(db).
161
+ */
162
+ export function loadFromDb(db) {
163
+ if (!db) return 0;
164
+ _sessions.clear();
165
+ _adrs.clear();
166
+
167
+ const parse = (v, fallback) => {
168
+ if (v == null) return fallback;
169
+ try {
170
+ return JSON.parse(v);
171
+ } catch {
172
+ return fallback;
173
+ }
174
+ };
175
+
176
+ const sessionRows = db.prepare(`SELECT * FROM dev_sessions`).all();
177
+ for (const row of sessionRows) {
178
+ _sessions.set(row.session_id, {
179
+ sessionId: row.session_id,
180
+ requirement: row.requirement,
181
+ currentPhase: row.current_phase,
182
+ status: row.status,
183
+ autonomyLevel: row.autonomy_level ?? 2,
184
+ codeChanges: parse(row.code_changes, []),
185
+ testResults: parse(row.test_results, null),
186
+ reviewFeedback: parse(row.review_feedback, null),
187
+ startedAt: row.started_at,
188
+ completedAt: row.completed_at ?? null,
189
+ createdBy: row.created_by ?? null,
190
+ updatedAt: row.updated_at,
191
+ _seq: ++_seq,
192
+ });
193
+ }
194
+
195
+ const adrRows = db.prepare(`SELECT * FROM architecture_decisions`).all();
196
+ for (const row of adrRows) {
197
+ _adrs.set(row.adr_id, {
198
+ adrId: row.adr_id,
199
+ sessionId: row.session_id,
200
+ title: row.title,
201
+ context: row.context,
202
+ decision: row.decision,
203
+ consequences: row.consequences ?? "",
204
+ alternatives: parse(row.alternatives, []),
205
+ status: row.status,
206
+ createdAt: row.created_at,
207
+ _seq: ++_seq,
208
+ });
209
+ }
210
+
211
+ return _sessions.size + _adrs.size;
212
+ }
213
+
154
214
  /* ── Catalogs ──────────────────────────────────────────────── */
155
215
 
156
216
  export function listAutonomyLevels() {
@@ -134,6 +134,11 @@ export async function streamOllama(
134
134
  const reader = response.body.getReader();
135
135
  const decoder = new TextDecoder();
136
136
  let fullResponse = "";
137
+ // Buffer incomplete lines across reads: an NDJSON line can be split across two
138
+ // stream chunks (TCP doesn't align to '\n'), so parsing each chunk in
139
+ // isolation would drop the split line entirely (both halves fail JSON.parse).
140
+ // Keep the trailing partial for the next read — same pattern as streamAnthropic.
141
+ let buf = "";
137
142
 
138
143
  try {
139
144
  while (true) {
@@ -141,10 +146,12 @@ export async function streamOllama(
141
146
  if (done) break;
142
147
  guard.bump();
143
148
 
144
- const text = decoder.decode(value, { stream: true });
145
- const lines = text.split("\n").filter(Boolean);
149
+ buf += decoder.decode(value, { stream: true });
150
+ const lines = buf.split("\n");
151
+ buf = lines.pop() || "";
146
152
 
147
153
  for (const line of lines) {
154
+ if (!line) continue;
148
155
  try {
149
156
  const json = JSON.parse(line);
150
157
  if (json.message?.content) {
@@ -225,6 +232,11 @@ export async function streamOpenAI(
225
232
  const reader = response.body.getReader();
226
233
  const decoder = new TextDecoder();
227
234
  let fullResponse = "";
235
+ // Buffer incomplete lines across reads: an SSE `data:` line can be split
236
+ // across two stream chunks, so parsing each chunk in isolation would drop the
237
+ // split line (both halves fail JSON.parse) — losing content and usage. Keep
238
+ // the trailing partial for the next read — same pattern as streamAnthropic.
239
+ let buf = "";
228
240
 
229
241
  try {
230
242
  while (true) {
@@ -232,8 +244,9 @@ export async function streamOpenAI(
232
244
  if (done) break;
233
245
  guard.bump();
234
246
 
235
- const text = decoder.decode(value, { stream: true });
236
- const lines = text.split("\n").filter(Boolean);
247
+ buf += decoder.decode(value, { stream: true });
248
+ const lines = buf.split("\n");
249
+ buf = lines.pop() || "";
237
250
 
238
251
  for (const line of lines) {
239
252
  if (line.startsWith("data: ")) {
@@ -129,6 +129,62 @@ export function ensureGovernanceTables(db) {
129
129
  );
130
130
  }
131
131
 
132
+ /**
133
+ * Rehydrate _decisions/_agentLevels from the persisted governance_decisions/
134
+ * autonomy_levels tables. The `cc` CLI runs every command in a fresh process, so
135
+ * without this the Maps start empty and a decision/level set in a prior
136
+ * invocation is invisible (`cc collab decisions`/`show`/`agents` show nothing),
137
+ * decision voting throws "not found", and setAutonomyLevel on a cold Map takes
138
+ * the INSERT branch on an already-persisted agent_id → PRIMARY KEY conflict.
139
+ * Call after ensureGovernanceTables(db).
140
+ */
141
+ export function loadFromDb(db) {
142
+ if (!db) return 0;
143
+ _decisions.clear();
144
+ _agentLevels.clear();
145
+
146
+ const parse = (v, fallback) => {
147
+ if (v == null) return fallback;
148
+ try {
149
+ return JSON.parse(v);
150
+ } catch {
151
+ return fallback;
152
+ }
153
+ };
154
+
155
+ const decisionRows = db.prepare(`SELECT * FROM governance_decisions`).all();
156
+ for (const row of decisionRows) {
157
+ _decisions.set(row.decision_id, {
158
+ decisionId: row.decision_id,
159
+ type: row.type,
160
+ proposal: row.proposal,
161
+ status: row.status,
162
+ votes: parse(row.votes, {}),
163
+ resolution: row.resolution ?? null,
164
+ executedAt: row.executed_at ?? null,
165
+ createdAt: row.created_at,
166
+ updatedAt: row.updated_at,
167
+ _seq: ++_seq,
168
+ });
169
+ }
170
+
171
+ const levelRows = db.prepare(`SELECT * FROM autonomy_levels`).all();
172
+ for (const row of levelRows) {
173
+ _agentLevels.set(row.agent_id, {
174
+ agentId: row.agent_id,
175
+ currentLevel: row.current_level,
176
+ permissions: parse(row.permissions, []),
177
+ adjustmentHistory: parse(row.adjustment_history, []),
178
+ lastReviewAt: row.last_review_at ?? null,
179
+ createdAt: row.created_at,
180
+ updatedAt: row.updated_at,
181
+ _seq: ++_seq,
182
+ });
183
+ }
184
+
185
+ return _decisions.size + _agentLevels.size;
186
+ }
187
+
132
188
  /* ── Catalogs ──────────────────────────────────────────────── */
133
189
 
134
190
  export function listDecisionTypes() {
@@ -129,6 +129,74 @@ export function ensureGovernanceTables(db) {
129
129
  );
130
130
  }
131
131
 
132
+ /**
133
+ * Rehydrate _proposals/_votes/_proposalVotes from the persisted
134
+ * governance_proposals/governance_votes tables. The `cc` CLI runs every command
135
+ * in a fresh process, so without this the Maps start empty and a proposal/vote
136
+ * created in a prior invocation is invisible (`cc governance list`/`show`/
137
+ * `votes`/`tally`/`stats` show nothing) and activate/close/castVote throw
138
+ * "Proposal not found". Rebuilds the _proposalVotes proposalId→Set<voteId>
139
+ * index from the votes too. Call after ensureGovernanceTables(db).
140
+ */
141
+ export function loadFromDb(db) {
142
+ if (!db) return 0;
143
+ _proposals.clear();
144
+ _votes.clear();
145
+ _proposalVotes.clear();
146
+
147
+ const parse = (v, fallback) => {
148
+ if (v == null) return fallback;
149
+ try {
150
+ return JSON.parse(v);
151
+ } catch {
152
+ return fallback;
153
+ }
154
+ };
155
+
156
+ const proposalRows = db.prepare(`SELECT * FROM governance_proposals`).all();
157
+ for (const row of proposalRows) {
158
+ _proposals.set(row.id, {
159
+ id: row.id,
160
+ title: row.title,
161
+ description: row.description ?? null,
162
+ type: row.type,
163
+ proposerDid: row.proposer_did ?? null,
164
+ status: row.status,
165
+ impactLevel: row.impact_level ?? null,
166
+ impactAnalysis: parse(row.impact_analysis, null),
167
+ voteYes: row.vote_yes ?? 0,
168
+ voteNo: row.vote_no ?? 0,
169
+ voteAbstain: row.vote_abstain ?? 0,
170
+ votingStartsAt: row.voting_starts_at ?? null,
171
+ votingEndsAt: row.voting_ends_at ?? null,
172
+ metadata: parse(row.metadata, null),
173
+ createdAt: row.created_at,
174
+ _seq: ++_seq,
175
+ });
176
+ _proposalVotes.set(row.id, new Set());
177
+ }
178
+
179
+ const voteRows = db.prepare(`SELECT * FROM governance_votes`).all();
180
+ for (const row of voteRows) {
181
+ _votes.set(row.id, {
182
+ id: row.id,
183
+ proposalId: row.proposal_id,
184
+ voterDid: row.voter_did,
185
+ vote: row.vote,
186
+ reason: row.reason ?? null,
187
+ weight: row.weight ?? 1.0,
188
+ createdAt: row.created_at,
189
+ _seq: ++_seq,
190
+ });
191
+ if (!_proposalVotes.has(row.proposal_id)) {
192
+ _proposalVotes.set(row.proposal_id, new Set());
193
+ }
194
+ _proposalVotes.get(row.proposal_id).add(row.id);
195
+ }
196
+
197
+ return _proposals.size + _votes.size;
198
+ }
199
+
132
200
  /* ── Catalogs ──────────────────────────────────────────────── */
133
201
 
134
202
  export function listProposalTypes() {
@@ -723,6 +723,69 @@ export function _resetState() {
723
723
  _reportRetentionMs = COMPLIANCE_DEFAULT_REPORT_RETENTION_MS;
724
724
  }
725
725
 
726
+ /**
727
+ * Rehydrate the in-memory _evidence/_policies Maps from the persisted
728
+ * compliance_* tables. The CLI runs each `cc compliance` subcommand in a fresh
729
+ * node process, so both Maps start empty every invocation. collectEvidence/
730
+ * addPolicy dual-write (Map + INSERT into compliance_evidence/compliance_policies)
731
+ * but generateReport (summary path), scanCompliance and listPolicies read the
732
+ * Maps only — so a `report`/`scan` after `evidence` in a separate process saw 0
733
+ * evidence items and scored 0. (The `report --detailed` path already SELECTed via
734
+ * the command-layer _loadEvidenceFromDb/_loadPoliciesFromDb; this makes the
735
+ * summary/scan/policies paths consistent.) `_reports` is write-only (no read
736
+ * path) and is not rehydrated. Call after ensureComplianceTables(db).
737
+ */
738
+ export function loadFromDb(db) {
739
+ if (!db) return 0;
740
+ ensureComplianceTables(db);
741
+ _evidence.clear();
742
+ _policies.clear();
743
+
744
+ for (const r of db
745
+ .prepare(
746
+ `SELECT id, framework, type, description, source, status, collected_at
747
+ FROM compliance_evidence ORDER BY collected_at ASC`,
748
+ )
749
+ .all()) {
750
+ _evidence.set(r.id, {
751
+ id: r.id,
752
+ framework: r.framework,
753
+ type: r.type,
754
+ description: r.description || "",
755
+ source: r.source,
756
+ status: r.status,
757
+ collectedAt: r.collected_at,
758
+ });
759
+ }
760
+
761
+ for (const r of db
762
+ .prepare(
763
+ `SELECT id, name, type, framework, rules, enabled, severity, created_at
764
+ FROM compliance_policies ORDER BY created_at ASC`,
765
+ )
766
+ .all()) {
767
+ // One corrupt rules cell must not sink the whole policy load.
768
+ let rules = {};
769
+ try {
770
+ rules = r.rules ? JSON.parse(r.rules) : {};
771
+ } catch {
772
+ rules = {};
773
+ }
774
+ _policies.set(r.id, {
775
+ id: r.id,
776
+ name: r.name,
777
+ type: r.type,
778
+ framework: r.framework,
779
+ rules,
780
+ enabled: !!r.enabled,
781
+ severity: r.severity,
782
+ createdAt: r.created_at,
783
+ });
784
+ }
785
+
786
+ return _evidence.size + _policies.size;
787
+ }
788
+
726
789
  // =====================================================================
727
790
  // compliance-manager V2 governance overlay (iter17)
728
791
  // =====================================================================
@@ -651,6 +651,11 @@ const BASE_FEE = {
651
651
  export function estimateFee({ fromChain, toChain, amount }) {
652
652
  if (!_validateChain(fromChain) || !_validateChain(toChain))
653
653
  return { fee: null, reason: "unsupported_chain" };
654
+ // `cc crosschain estimate-fee` passes parseFloat(amount); a non-numeric arg
655
+ // yields NaN. Without this guard percentageFee/totalFee become NaN, the
656
+ // command's `fee === null` check misses it, and it prints "$NaN USD".
657
+ if (!Number.isFinite(amount) || amount <= 0)
658
+ return { fee: null, reason: "invalid_amount" };
654
659
 
655
660
  const baseFee = (BASE_FEE[fromChain] || 1.0) + (BASE_FEE[toChain] || 1.0);
656
661
  const percentageFee = amount * (DEFAULT_CONFIG.feePercentage / 100);
@@ -112,6 +112,153 @@ export function ensureDAOv2Tables(db) {
112
112
  `);
113
113
  }
114
114
 
115
+ /**
116
+ * Hydrate the in-memory stores from the DB. The CLI is one-shot: _proposals/
117
+ * _votes/_delegations/_treasury/_delegationsV2/_treasuryTxs all start empty each
118
+ * process. Every write dual-writes (Map/obj + INSERT) but every read/mutate is
119
+ * Map-only and nothing SELECTed the tables back — so the ENTIRE dao feature was
120
+ * broken across invocations: vote/execute/allocate threw "not found", stats
121
+ * reported 0, and the treasury deposit was invisible (allocate always
122
+ * "Insufficient"). Call after ensureDAOv2Tables(db).
123
+ *
124
+ * Faithful: proposals' votesFor/votesAgainst/status, votes, legacy delegations,
125
+ * and the treasury balance (DERIVED = Σdeposit − Σallocation, replayed in
126
+ * chronological order so each tx's balanceAfter is reconstructed too).
127
+ *
128
+ * Lossy (defaulted to stay correct/safe — these columns don't exist in the
129
+ * schema): V2 proposal abstain/quadratic-weight tallies → 0; proposal.queueEnd →
130
+ * a far-future sentinel so executeProposalV2 FAILS CLOSED (a null/undefined
131
+ * would make its timelock check `now < NaN` and BYPASS the timelock); V2
132
+ * delegation status/expiresAt → ACTIVE/none (revocation is not persisted).
133
+ */
134
+ const _REHYDRATE_QUEUE_END_SENTINEL = "9999-12-31T23:59:59.999Z";
135
+
136
+ export function loadFromDb(db) {
137
+ if (!db) return 0;
138
+ ensureDAOv2Tables(db);
139
+ _proposals.clear();
140
+ _votes.clear();
141
+ _delegations.clear();
142
+ _delegationsV2.clear();
143
+ _treasuryTxs.length = 0;
144
+ _treasury.balance = 0;
145
+ _treasury.allocations = [];
146
+
147
+ for (const r of db
148
+ .prepare(
149
+ `SELECT id, title, description, proposer, status, votes_for, votes_against, voting_type, created_at, ends_at, executed_at
150
+ FROM dao_v2_proposals`,
151
+ )
152
+ .all()) {
153
+ _proposals.set(r.id, {
154
+ id: r.id,
155
+ title: r.title,
156
+ description: r.description || "",
157
+ proposer: r.proposer,
158
+ proposerDid: r.proposer, // V2 field mirrors legacy proposer
159
+ type: "standard",
160
+ status: r.status,
161
+ votesFor: Number(r.votes_for) || 0,
162
+ votesAgainst: Number(r.votes_against) || 0,
163
+ votingType: r.voting_type,
164
+ createdAt: r.created_at,
165
+ updatedAt: r.created_at,
166
+ endsAt: r.ends_at,
167
+ executedAt: r.executed_at,
168
+ // Non-persisted V2 fields — default to stay NaN-safe (see fn doc).
169
+ votesAbstain: 0,
170
+ quadraticWeightFor: 0,
171
+ quadraticWeightAgainst: 0,
172
+ quorumReached: false,
173
+ votingStart: null,
174
+ votingEnd: null,
175
+ cancelledAt: null,
176
+ // Fail-closed: a rehydrated QUEUED proposal cannot be executed until it is
177
+ // re-queued (real queueEnd is not persisted). Never bypass the timelock.
178
+ queueEnd: _REHYDRATE_QUEUE_END_SENTINEL,
179
+ });
180
+ }
181
+
182
+ for (const r of db
183
+ .prepare(
184
+ `SELECT id, proposal_id, voter, weight, direction, delegated_from, created_at
185
+ FROM dao_v2_votes`,
186
+ )
187
+ .all()) {
188
+ _votes.set(r.id, {
189
+ id: r.id,
190
+ proposalId: r.proposal_id,
191
+ voter: r.voter,
192
+ voterDid: r.voter, // both read paths (stats uses voter, anti-sybil voterDid)
193
+ weight: Number(r.weight) || 0,
194
+ voteCount: Number(r.weight) || 0,
195
+ direction: r.direction,
196
+ voteType: r.direction,
197
+ delegatedFrom: r.delegated_from,
198
+ createdAt: r.created_at,
199
+ });
200
+ }
201
+
202
+ for (const r of db
203
+ .prepare(
204
+ `SELECT delegator, delegate, weight, created_at FROM dao_v2_delegations`,
205
+ )
206
+ .all()) {
207
+ _delegations.set(r.delegator, {
208
+ delegator: r.delegator,
209
+ delegate: r.delegate,
210
+ weight: Number(r.weight) || 0,
211
+ });
212
+ // Synthesize a V2 record (status/expiresAt are not persisted → default).
213
+ _delegationsV2.set(`deleg:${r.delegator}`, {
214
+ id: `deleg:${r.delegator}`,
215
+ fromDid: r.delegator,
216
+ toDid: r.delegate,
217
+ weight: Number(r.weight) || 0,
218
+ status: DELEGATION_STATUS.ACTIVE,
219
+ expiresAt: null,
220
+ revokedAt: null,
221
+ createdAt: r.created_at,
222
+ });
223
+ }
224
+
225
+ // Treasury: no balance column — derive it by replaying the tx log in
226
+ // chronological order (deposit +, allocation −), reconstructing balanceAfter.
227
+ const treasuryRows = db
228
+ .prepare(
229
+ `SELECT id, type, amount, description, proposal_id, created_at
230
+ FROM dao_v2_treasury ORDER BY created_at ASC`,
231
+ )
232
+ .all();
233
+ for (const r of treasuryRows) {
234
+ const amt = Number(r.amount) || 0;
235
+ if (r.type === TREASURY_TX_TYPE.DEPOSIT) _treasury.balance += amt;
236
+ else if (r.type === TREASURY_TX_TYPE.ALLOCATION) _treasury.balance -= amt;
237
+ _treasuryTxs.push({
238
+ id: r.id,
239
+ txType: r.type,
240
+ proposalId: r.proposal_id,
241
+ amount: amt,
242
+ memo: r.description || "",
243
+ balanceAfter: _treasury.balance,
244
+ createdAt: r.created_at,
245
+ });
246
+ if (r.type === TREASURY_TX_TYPE.ALLOCATION) {
247
+ _treasury.allocations.push({
248
+ id: r.id,
249
+ proposalId: r.proposal_id,
250
+ amount: amt,
251
+ description: r.description || "",
252
+ date: r.created_at,
253
+ });
254
+ }
255
+ }
256
+
257
+ return (
258
+ _proposals.size + _votes.size + _delegations.size + _treasuryTxs.length
259
+ );
260
+ }
261
+
115
262
  /* ── Proposals ─────────────────────────────────────────────── */
116
263
 
117
264
  export function propose(db, title, description, proposer, options = {}) {
@@ -259,7 +406,8 @@ export function getTreasury() {
259
406
 
260
407
  export function allocate(db, proposalId, amount, description) {
261
408
  if (!proposalId) throw new Error("Proposal ID is required");
262
- if (amount <= 0) throw new Error("Amount must be positive");
409
+ if (!Number.isFinite(amount) || amount <= 0)
410
+ throw new Error("Amount must be positive");
263
411
  if (_treasury.balance < amount) {
264
412
  throw new Error("Insufficient treasury balance");
265
413
  }
@@ -287,7 +435,8 @@ export function allocate(db, proposalId, amount, description) {
287
435
  }
288
436
 
289
437
  export function depositToTreasury(db, amount, description) {
290
- if (amount <= 0) throw new Error("Amount must be positive");
438
+ if (!Number.isFinite(amount) || amount <= 0)
439
+ throw new Error("Amount must be positive");
291
440
 
292
441
  const id = `dep-${Date.now()}-${crypto.randomBytes(4).toString("hex")}`;
293
442
  const now = new Date().toISOString();
@@ -163,16 +163,29 @@ export function setDefaultIdentity(db, did) {
163
163
  const identity = getIdentity(db, did);
164
164
  if (!identity) return false;
165
165
 
166
- // Clear the current default(s). Match on is_default rather than `did LIKE '%'`
167
- // so there's no wildcard pattern here that a reader/scanner could mistake for
168
- // LIKE-injection — the target below is set via exact `did = ?` regardless.
169
- db.prepare(
170
- "UPDATE did_identities SET is_default = 0 WHERE is_default = 1",
171
- ).run();
172
- db.prepare("UPDATE did_identities SET is_default = ? WHERE did = ?").run(
173
- 1,
174
- identity.did,
175
- );
166
+ // Clear the current default(s) then set the new one atomically. Match on
167
+ // is_default rather than `did LIKE '%'` so there's no wildcard pattern here
168
+ // that a reader/scanner could mistake for LIKE-injection — the target below
169
+ // is set via exact `did = ?` regardless.
170
+ //
171
+ // The two UPDATEs must both land: without a transaction, a failure on the
172
+ // second leaves EVERY identity non-default (the default DID silently
173
+ // disappears until manually re-set), breaking the exactly-one-default
174
+ // invariant.
175
+ const applyWrites = () => {
176
+ db.prepare(
177
+ "UPDATE did_identities SET is_default = 0 WHERE is_default = 1",
178
+ ).run();
179
+ db.prepare("UPDATE did_identities SET is_default = ? WHERE did = ?").run(
180
+ 1,
181
+ identity.did,
182
+ );
183
+ };
184
+ if (db && typeof db.transaction === "function") {
185
+ db.transaction(applyWrites)();
186
+ } else {
187
+ applyWrites();
188
+ }
176
189
  return true;
177
190
  }
178
191
 
@@ -325,6 +325,76 @@ export function _resetState() {
325
325
  _v2IncidentMeta.clear();
326
326
  }
327
327
 
328
+ /**
329
+ * Rehydrate the in-memory _policies/_incidents Maps from the persisted dlp_*
330
+ * tables. The CLI runs each `cc dlp` subcommand in a fresh node process, so both
331
+ * Maps start empty every invocation. createPolicy/scanContent dual-write (Map +
332
+ * INSERT into dlp_policies/dlp_incidents) but every read (listDLPPolicies/
333
+ * listIncidents/getDLPStats + the scanContent enforcement loop over _policies)
334
+ * is Map-only and nothing SELECTed the tables back.
335
+ *
336
+ * SECURITY IMPACT: `cc dlp scan` iterates an empty _policies → matches nothing →
337
+ * returns allowed:true, so a BLOCK policy created in a prior invocation silently
338
+ * never enforces. Persisted policies were also un-listable and un-deletable
339
+ * (`policy delete`/`resolve` threw "not found"). Call after ensureDLPTables(db).
340
+ */
341
+ export function loadFromDb(db) {
342
+ if (!db) return 0;
343
+ ensureDLPTables(db);
344
+ _policies.clear();
345
+ _incidents.clear();
346
+
347
+ const parse = (v, fallback) => {
348
+ try {
349
+ return v ? JSON.parse(v) : fallback;
350
+ } catch {
351
+ return fallback;
352
+ }
353
+ };
354
+
355
+ for (const r of db
356
+ .prepare(
357
+ `SELECT id, name, patterns, keywords, action, severity, enabled, created_at
358
+ FROM dlp_policies ORDER BY created_at ASC`,
359
+ )
360
+ .all()) {
361
+ _policies.set(r.id, {
362
+ id: r.id,
363
+ name: r.name,
364
+ patterns: parse(r.patterns, []),
365
+ keywords: parse(r.keywords, []),
366
+ action: r.action,
367
+ severity: r.severity,
368
+ enabled: !!r.enabled,
369
+ createdAt: r.created_at,
370
+ });
371
+ }
372
+
373
+ for (const r of db
374
+ .prepare(
375
+ `SELECT id, policy_id, channel, action_taken, content_hash, matched_patterns,
376
+ severity, user_id, created_at, resolved_at, resolution
377
+ FROM dlp_incidents ORDER BY created_at ASC`,
378
+ )
379
+ .all()) {
380
+ _incidents.set(r.id, {
381
+ id: r.id,
382
+ policyId: r.policy_id,
383
+ channel: r.channel,
384
+ actionTaken: r.action_taken,
385
+ contentHash: r.content_hash,
386
+ matchedPatterns: parse(r.matched_patterns, []),
387
+ severity: r.severity,
388
+ userId: r.user_id,
389
+ createdAt: r.created_at,
390
+ resolvedAt: r.resolved_at ?? null,
391
+ resolution: r.resolution ?? null,
392
+ });
393
+ }
394
+
395
+ return _policies.size + _incidents.size;
396
+ }
397
+
328
398
  // ═══════════════════════════════════════════════════════════════
329
399
  // V2 Canonical Surface (Phase 50)
330
400
  // ═══════════════════════════════════════════════════════════════