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
@@ -217,9 +217,10 @@ export class TeamRunner {
217
217
  mailbox: this.mailbox,
218
218
  budget: this.budget,
219
219
  });
220
- this.registry.complete(key, { holder, result });
221
- // Fold usage/cost into the team budget. `--exec` shell tasks carry no
222
- // usage only the task-count / wall-clock dimensions move.
220
+ const done = this.registry.complete(key, { holder, result });
221
+ // Fold usage/cost into the team budget regardless the task DID execute
222
+ // and consumed resources. `--exec` shell tasks carry no usage → only the
223
+ // task-count / wall-clock dimensions move.
223
224
  if (this.budget) {
224
225
  this.budget.record(
225
226
  {
@@ -230,12 +231,27 @@ export class TeamRunner {
230
231
  this._now(),
231
232
  );
232
233
  }
233
- this._setState(holder, "completed-task");
234
- this._emit("task:completed", {
235
- key,
236
- holder,
237
- ms: this._now() - startedAt,
238
- });
234
+ if (done.ok) {
235
+ this._setState(holder, "completed-task");
236
+ this._emit("task:completed", {
237
+ key,
238
+ holder,
239
+ ms: this._now() - startedAt,
240
+ });
241
+ } else {
242
+ // The registry REJECTED the completion — the lease expired mid-run (the
243
+ // task outran its TTL without renewing), so a peer may already own it.
244
+ // Reporting `task:completed` + bumping the completed counter here would
245
+ // be a phantom success (the registry has no record of it, and the task
246
+ // will be reclaimed and re-run). Surface the discard honestly instead so
247
+ // the event stream and per-teammate stats stay truthful.
248
+ this._emit("task:completion-discarded", {
249
+ key,
250
+ holder,
251
+ reason: done.reason,
252
+ ms: this._now() - startedAt,
253
+ });
254
+ }
239
255
  } catch (err) {
240
256
  // A failed task still consumed a task-count slot (and any wall-clock) — fold
241
257
  // it so a doomed retry loop can't dodge the budget.
@@ -96,6 +96,24 @@ export class TeamWorktreeCoordinator {
96
96
  makeRunTask({ runInWorktree = null } = {}) {
97
97
  return async ({ key, task, holder }) => {
98
98
  const branch = this.branchFor(key);
99
+ // A retry (the prior attempt failed and TaskLeaseRegistry re-queued the
100
+ // task) would collide with its own leftover worktree: createWorktree
101
+ // derives a DETERMINISTIC path from the branch and throws "Worktree
102
+ // already exists" (and `worktree add -b` rejects the existing branch), so
103
+ // the retry can never recover — it just re-fails on the collision instead
104
+ // of the real task. Tear down the prior attempt's worktree + branch first
105
+ // so a retry starts clean.
106
+ const prior = this._created.get(key);
107
+ if (prior) {
108
+ try {
109
+ _deps.removeWorktree(this.repoDir, prior.path, {
110
+ deleteBranch: true,
111
+ });
112
+ } catch {
113
+ /* best-effort — a real problem will resurface in createWorktree */
114
+ }
115
+ this._created.delete(key);
116
+ }
99
117
  const { path: worktreePath } = _deps.createWorktree(this.repoDir, branch);
100
118
  this._created.set(key, { branch, path: worktreePath, committed: false });
101
119
  if (typeof runInWorktree === "function") {
@@ -157,20 +175,34 @@ export class TeamWorktreeCoordinator {
157
175
  const conflicts = preview?.conflicts || [];
158
176
  let merged = false;
159
177
  if (clean && merge) {
178
+ // mergeWorktree does NOT throw on a failed merge — it catches internally
179
+ // and RETURNS {success:false, conflicts?, message} (a conflict the clean
180
+ // preview didn't predict, or any non-conflict git failure). The old
181
+ // try/catch was dead for that path and set merged:true unconditionally,
182
+ // reporting a real merge failure as success with empty conflicts. Inspect
183
+ // the return value. (The try still catches assertSafeGitRef, the only
184
+ // throw path — a malformed branch ref.)
185
+ let mergeResult;
160
186
  try {
161
- _deps.mergeWorktree(this.repoDir, info.branch, {
187
+ mergeResult = _deps.mergeWorktree(this.repoDir, info.branch, {
162
188
  message: `Merge team task ${key}`,
163
189
  });
164
- merged = true;
165
190
  } catch (err) {
191
+ mergeResult = { success: false, message: err.message };
192
+ }
193
+ if (mergeResult?.success === true) {
194
+ merged = true;
195
+ } else {
166
196
  results.push({
167
197
  key,
168
198
  branch: info.branch,
169
199
  committed: true,
170
200
  clean: false,
171
201
  merged: false,
172
- conflicts,
173
- error: `merge failed: ${err.message}`,
202
+ conflicts: mergeResult?.conflicts?.length
203
+ ? mergeResult.conflicts
204
+ : conflicts,
205
+ error: `merge failed: ${mergeResult?.message || "unknown error"}`,
174
206
  });
175
207
  continue;
176
208
  }
@@ -23,9 +23,10 @@
23
23
  * flight — a rapid PostToolUse hook can't stack N copies of itself;
24
24
  * - a maxConcurrent cap — overflow is DROPPED with a recorded skip, never
25
25
  * queued unbounded;
26
- * - a per-hook timeout that kills the child;
27
- * - reaping of every child on stopAll() / process 'exit', so a session never
28
- * leaves an orphan hook process.
26
+ * - a per-hook timeout that TREE-kills the child (shell + the real command it
27
+ * spawned a bare child.kill would orphan the grandchild);
28
+ * - tree-reaping of every child on stopAll() / process 'exit', so a session
29
+ * never leaves an orphan hook process.
29
30
  *
30
31
  * `_deps.spawn` / `_deps.now` are injected so the whole supervisor is unit-
31
32
  * testable with fake child processes (no real shell).
@@ -37,6 +38,12 @@ const { tryParseDecision } = require("./hook-runner.cjs");
37
38
  const DEFAULT_TIMEOUT_MS = 60000;
38
39
  const MAX_TIMEOUT_MS = 600000;
39
40
  const DEFAULT_MAX_CONCURRENT = 4;
41
+ // Ring cap on undrained records (parity with PluginMonitorSupervisor's
42
+ // OUTPUT_RING): drainResults()/drainRewakes() normally clear each turn, but a
43
+ // stalled/absent drain over a high-frequency hook would otherwise grow these
44
+ // arrays without bound. Keep only the most recent RESULT_RING; older records
45
+ // are dropped oldest-first.
46
+ const RESULT_RING = 500;
40
47
 
41
48
  class AsyncHookSupervisor {
42
49
  constructor(opts = {}) {
@@ -46,20 +53,87 @@ class AsyncHookSupervisor {
46
53
  : DEFAULT_MAX_CONCURRENT;
47
54
  this._deps = {
48
55
  spawn: opts.spawn || cpDefault.spawn,
56
+ spawnSync: opts.spawnSync || cpDefault.spawnSync,
49
57
  now: opts.now || (() => Date.now()),
50
58
  };
51
59
  this._running = new Map(); // key -> { child, timer }
52
60
  this._results = []; // completed records awaiting drainResults()
53
61
  this._rewakes = []; // failed asyncRewake records awaiting drainRewakes()
54
62
  this._stopped = false;
63
+ // The exit reaper is installed LAZILY (on first spawn), not in the ctor:
64
+ // a supervisor that never dispatches a hook (or the many built in tests)
65
+ // must not leave a permanent `process.once('exit')` listener behind —
66
+ // that accumulates across sessions/instances into a MaxListenersExceeded
67
+ // leak. Mirrors PluginMonitorSupervisor._installExitHook.
55
68
  this._exitHook = () => this.stopAll();
56
- process.once("exit", this._exitHook);
69
+ this._exitHookInstalled = false;
57
70
  }
58
71
 
59
72
  _key(hook) {
60
73
  return `${hook.event || ""}::${hook.command}`;
61
74
  }
62
75
 
76
+ /**
77
+ * Kill a hook child's WHOLE process tree. Hooks run with `shell: true`, so the
78
+ * real command is a grandchild of the shell — a plain `child.kill()` only
79
+ * signals the shell (POSIX: reparents + keeps the command running; Windows:
80
+ * killing cmd.exe never touches its children), orphaning the actual hook
81
+ * process. POSIX: the child is spawned detached (its own group), so a negative
82
+ * pid signals the whole group. Windows: `taskkill /T` walks the tree. Both are
83
+ * SYNCHRONOUS (spawnSync / process.kill) so this is safe inside stopAll() and
84
+ * the process 'exit' reaper, where async work would be cut off. A child with no
85
+ * real pid (the unit-test fakes) falls back to its own `.kill()`.
86
+ */
87
+ _killChildTree(child, signal = "SIGTERM") {
88
+ if (!child) return;
89
+ const pid = child.pid;
90
+ if (typeof pid !== "number" || pid <= 0) {
91
+ try {
92
+ child.kill(signal);
93
+ } catch {
94
+ /* already gone / fake with no kill */
95
+ }
96
+ return;
97
+ }
98
+ try {
99
+ if (process.platform === "win32") {
100
+ const r = this._deps.spawnSync(
101
+ "taskkill",
102
+ ["/pid", String(pid), "/T", "/F"],
103
+ { windowsHide: true },
104
+ );
105
+ // If taskkill couldn't launch, fall back to a direct kill.
106
+ if (r && r.error) child.kill(signal);
107
+ } else {
108
+ // Negative pid → the whole process group (requires the detached spawn).
109
+ try {
110
+ process.kill(-pid, signal);
111
+ } catch {
112
+ child.kill(signal);
113
+ }
114
+ }
115
+ } catch {
116
+ try {
117
+ child.kill(signal);
118
+ } catch {
119
+ /* already gone */
120
+ }
121
+ }
122
+ }
123
+
124
+ /** Install the process-exit reaper exactly once, only when a child exists. */
125
+ _installExitHook() {
126
+ if (this._exitHookInstalled) return;
127
+ this._exitHookInstalled = true;
128
+ process.once("exit", this._exitHook);
129
+ }
130
+
131
+ /** Append a result record, bounded to the most recent RESULT_RING. */
132
+ _pushResult(rec) {
133
+ this._results.push(rec);
134
+ if (this._results.length > RESULT_RING) this._results.shift();
135
+ }
136
+
63
137
  /**
64
138
  * Dispatch a batch of async hooks fire-and-forget. Returns IMMEDIATELY with a
65
139
  * per-hook disposition (`{command, dispatched, reason?}`) — it never awaits a
@@ -100,7 +174,7 @@ class AsyncHookSupervisor {
100
174
  });
101
175
  // Record the skip so the caller/agent can SEE that a hook was dropped
102
176
  // (silent truncation would read as "the hook ran and said nothing").
103
- this._results.push({
177
+ this._pushResult({
104
178
  command: hook.command,
105
179
  event: hook.event || null,
106
180
  ok: false,
@@ -121,6 +195,9 @@ class AsyncHookSupervisor {
121
195
  }
122
196
 
123
197
  _spawnOne(hook, payload, opts) {
198
+ // A live child now exists — arm the exit reaper so a session never leaves
199
+ // an orphan hook process (installed once, only from here).
200
+ this._installExitHook();
124
201
  const key = this._key(hook);
125
202
  const started = this._deps.now();
126
203
  const rawTimeout = Number(
@@ -136,6 +213,10 @@ class AsyncHookSupervisor {
136
213
  child = this._deps.spawn(hook.command, {
137
214
  cwd: opts.cwd || process.cwd(),
138
215
  shell: true,
216
+ // POSIX: own process group so a timeout / stopAll can signal the whole
217
+ // tree (shell + the real hook command), not just the shell wrapper.
218
+ // No-op on Windows, where the tree is reaped via `taskkill /T` instead.
219
+ detached: process.platform !== "win32",
139
220
  env: {
140
221
  ...process.env,
141
222
  CLAUDE_HOOK_EVENT: hook.event || payload.hook_event_name || "",
@@ -158,6 +239,13 @@ class AsyncHookSupervisor {
158
239
  this._running.set(key, rec);
159
240
 
160
241
  try {
242
+ // `.end(data)` flushes ASYNCHRONOUSLY: if the hook exited before consuming
243
+ // stdin (a fast command), the write fails with an async EPIPE emitted as an
244
+ // 'error' event on the stream — NOT a sync throw this catch can see. With no
245
+ // listener that becomes an uncaught exception that crashes the process (seen
246
+ // on Linux CI). Attach a no-op error handler first so a closed-stdin write
247
+ // is swallowed as the non-fatal condition it is.
248
+ child.stdin?.on("error", () => {});
161
249
  child.stdin?.end(JSON.stringify(payload));
162
250
  } catch {
163
251
  /* stdin may already be closed — non-fatal */
@@ -171,11 +259,9 @@ class AsyncHookSupervisor {
171
259
 
172
260
  const timer = setTimeout(() => {
173
261
  killedByTimeout = true;
174
- try {
175
- child.kill("SIGTERM");
176
- } catch {
177
- /* already gone */
178
- }
262
+ // Tree-kill: a hook that spawned a subprocess (e.g. `npm test`) must not
263
+ // leave that subprocess orphaned when it exceeds its timeout.
264
+ this._killChildTree(child, "SIGTERM");
179
265
  }, timeout);
180
266
  if (typeof timer.unref === "function") timer.unref();
181
267
  rec.timer = timer;
@@ -240,11 +326,12 @@ class AsyncHookSupervisor {
240
326
  ts: now,
241
327
  ms: fields.started != null ? now - fields.started : 0,
242
328
  };
243
- this._results.push(rec);
329
+ this._pushResult(rec);
244
330
  // A rewake fires only for a hook that OPTED IN and finished in a failure
245
331
  // state — a passing async check should not re-engage the agent.
246
332
  if (hook.asyncRewake && !rec.ok) {
247
333
  this._rewakes.push(rec);
334
+ if (this._rewakes.length > RESULT_RING) this._rewakes.shift();
248
335
  }
249
336
  }
250
337
 
@@ -283,11 +370,9 @@ class AsyncHookSupervisor {
283
370
  } catch {
284
371
  /* ignore */
285
372
  }
286
- try {
287
- rec.child.kill("SIGTERM");
288
- } catch {
289
- /* already gone */
290
- }
373
+ // Tree-kill (not a bare child.kill) so a session end / process exit never
374
+ // leaves an orphaned hook subprocess — the guarantee this class documents.
375
+ this._killChildTree(rec.child, "SIGTERM");
291
376
  this._running.delete(key);
292
377
  }
293
378
  try {
@@ -295,6 +380,7 @@ class AsyncHookSupervisor {
295
380
  } catch {
296
381
  /* ignore */
297
382
  }
383
+ this._exitHookInstalled = false;
298
384
  }
299
385
  }
300
386
 
@@ -5,6 +5,7 @@
5
5
 
6
6
  import crypto from "crypto";
7
7
  import { safeJsonParse } from "./safe-json.js";
8
+ import { escapeLike } from "./sql-like.js";
8
9
 
9
10
  /**
10
11
  * Event types for audit logging.
@@ -183,13 +184,13 @@ export function queryLogs(db, filters = {}) {
183
184
  }
184
185
 
185
186
  if (filters.operation) {
186
- sql += " AND operation LIKE ?";
187
- params.push(`%${filters.operation}%`);
187
+ sql += " AND operation LIKE ? ESCAPE '\\'";
188
+ params.push(`%${escapeLike(filters.operation)}%`);
188
189
  }
189
190
 
190
191
  if (filters.actor) {
191
- sql += " AND actor LIKE ?";
192
- params.push(`%${filters.actor}%`);
192
+ sql += " AND actor LIKE ? ESCAPE '\\'";
193
+ params.push(`%${escapeLike(filters.actor)}%`);
193
194
  }
194
195
 
195
196
  if (filters.riskLevel) {
@@ -214,8 +215,8 @@ export function queryLogs(db, filters = {}) {
214
215
 
215
216
  if (filters.search) {
216
217
  // Search in operation field (primary search field for CLI)
217
- sql += " AND operation LIKE ?";
218
- params.push(`%${filters.search}%`);
218
+ sql += " AND operation LIKE ? ESCAPE '\\'";
219
+ params.push(`%${escapeLike(filters.search)}%`);
219
220
  }
220
221
 
221
222
  sql += " ORDER BY created_at DESC";
@@ -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
  // =====================================================================