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
@@ -28,6 +28,7 @@ export class RemoteCommandLedger {
28
28
  this._order = []; // applyIndex → commandId (total order)
29
29
  this._revoked = new Set(revokedDevices);
30
30
  this._perDeviceSeq = new Map(); // deviceId → highest accepted seq
31
+ this._inFlight = new Map(); // commandId → Promise<record> for an in-progress apply
31
32
  }
32
33
 
33
34
  isRevoked(deviceId) {
@@ -73,6 +74,28 @@ export class RemoteCommandLedger {
73
74
  };
74
75
  }
75
76
 
77
+ // Coalesce CONCURRENT deliveries of the same commandId. `execute` is awaited
78
+ // below, so without this a second delivery arriving while the first is still
79
+ // running would ALSO pass the `prior` check (nothing is recorded until
80
+ // execute resolves) and run the side effect a SECOND time — the exact
81
+ // double-exec this ledger exists to prevent on reconnect. An already-in-flight
82
+ // same-commandId delivery waits for it and returns its result as `replayed`.
83
+ const inflight = this._inFlight.get(commandId);
84
+ if (inflight) {
85
+ try {
86
+ const rec = await inflight;
87
+ return {
88
+ status: "replayed",
89
+ result: rec.result,
90
+ applyIndex: rec.applyIndex,
91
+ };
92
+ } catch {
93
+ // The in-flight execution failed → it recorded nothing and is retryable;
94
+ // report rejection to this caller too (it can retry the same commandId).
95
+ return { status: "rejected", reason: "concurrent execution failed" };
96
+ }
97
+ }
98
+
76
99
  // Optional per-device monotonic sequence check: a STALE seq (below what we've
77
100
  // already accepted from this device) with a NEW commandId is a protocol
78
101
  // violation (a genuine reconnect resends the SAME commandId, caught above).
@@ -85,28 +108,36 @@ export class RemoteCommandLedger {
85
108
  return { status: "rejected", reason: "stale sequence" };
86
109
  }
87
110
 
88
- let result;
111
+ // Reserve the commandId BEFORE the first await so a concurrent same-id
112
+ // delivery (above) sees it in flight. The promise records the applied result
113
+ // on success and rejects on failure (so a retry can re-run the side effect).
114
+ const runPromise = (async () => {
115
+ const result = await execute(command);
116
+ const applyIndex = this._order.length;
117
+ const rec = { applyIndex, result, deviceId, ts: this._now() };
118
+ this._applied.set(commandId, rec);
119
+ this._order.push(commandId);
120
+ if (deviceId != null && Number.isFinite(command.seq)) {
121
+ this._perDeviceSeq.set(deviceId, command.seq);
122
+ }
123
+ return rec;
124
+ })();
125
+ this._inFlight.set(commandId, runPromise);
89
126
  try {
90
- result = await execute(command);
127
+ const rec = await runPromise;
128
+ return {
129
+ status: "applied",
130
+ result: rec.result,
131
+ applyIndex: rec.applyIndex,
132
+ };
91
133
  } catch (err) {
92
134
  // A failed execution is NOT recorded as applied — the command may be
93
135
  // retried (with the same commandId) and will run again. Surfacing the
94
136
  // error lets the caller decide; idempotency only protects SUCCESSES.
95
137
  return { status: "rejected", reason: `execute failed: ${err.message}` };
138
+ } finally {
139
+ this._inFlight.delete(commandId);
96
140
  }
97
-
98
- const applyIndex = this._order.length;
99
- this._applied.set(commandId, {
100
- applyIndex,
101
- result,
102
- deviceId,
103
- ts: this._now(),
104
- });
105
- this._order.push(commandId);
106
- if (deviceId != null && Number.isFinite(command.seq)) {
107
- this._perDeviceSeq.set(deviceId, command.seq);
108
- }
109
- return { status: "applied", result, applyIndex };
110
141
  }
111
142
 
112
143
  /**
@@ -629,19 +629,29 @@ function _conflictStatusCode(repoDir, filePath) {
629
629
  }
630
630
 
631
631
  function _mapConflictType(statusCode) {
632
+ // NOTE: the porcelain XY code is reported relative to the ACTUAL merge, which
633
+ // previewWorktreeMerge/applyWorktreeAutomationCandidate run as `git merge
634
+ // <base>` INSIDE the agent worktree — i.e. ours=agent, theirs=base, the
635
+ // REVERSE of the "current merges in the agent branch" direction the candidate
636
+ // labels/suggestions describe. For symmetric codes (UU/AA) direction is
637
+ // irrelevant. For the asymmetric delete/add codes the U/D (us/them) halves
638
+ // must be swapped back to the label direction, otherwise the "keep the file"
639
+ // candidate checks out the side that DELETED it (`git checkout --ours/--theirs`
640
+ // → "path does not have our/their version") and throws — leaving no automated
641
+ // way to preserve the surviving file.
632
642
  switch (statusCode) {
633
643
  case "UU":
634
644
  return "both_modified";
635
645
  case "AA":
636
646
  return "both_added";
637
- case "DU":
638
- return "deleted_by_us";
639
- case "UD":
647
+ case "DU": // ours(agent) deleted, theirs(base) modified
640
648
  return "deleted_by_them";
641
- case "AU":
642
- return "added_by_us";
643
- case "UA":
649
+ case "UD": // ours(agent) modified, theirs(base) deleted
650
+ return "deleted_by_us";
651
+ case "AU": // added by ours(agent)
644
652
  return "added_by_them";
653
+ case "UA": // added by theirs(base)
654
+ return "added_by_us";
645
655
  default:
646
656
  return "unmerged";
647
657
  }
@@ -70,9 +70,12 @@ describe("quiet mode", () => {
70
70
  expect(logSpy).not.toHaveBeenCalled();
71
71
  });
72
72
 
73
- it("does NOT suppress warn (still console.log)", () => {
73
+ it("does NOT suppress warn (writes to console.error/stderr)", () => {
74
74
  warn("careful");
75
- expect(logSpy).toHaveBeenCalledTimes(1);
75
+ // warn goes to stderr (not stdout) so it never pollutes machine-readable
76
+ // stdout like `--json`; still never suppressed by quiet mode.
77
+ expect(errSpy).toHaveBeenCalledTimes(1);
78
+ expect(logSpy).not.toHaveBeenCalled();
76
79
  });
77
80
 
78
81
  it("does NOT suppress error", () => {
@@ -5,7 +5,6 @@
5
5
  * capability negotiation, and peer discovery.
6
6
  */
7
7
 
8
-
9
8
  // Safe JSON-array parse for values read back from the DB (capabilities / skills /
10
9
  // history / artifacts are stored as JSON strings). Written via JSON.stringify so
11
10
  // normally valid, but a corrupted or externally-edited DB must not crash agent
@@ -523,6 +522,31 @@ export function getCardStatusV2(cardId) {
523
522
  return _v2Cards.get(cardId)?.status || "active";
524
523
  }
525
524
 
525
+ /**
526
+ * Hydrate the in-memory _v2Cards Map from the DB. The CLI is one-shot: _v2Cards
527
+ * starts empty every process, so getCardStatusV2 always fell back to "active"
528
+ * and setCardStatus validated transitions against a phantom "active" prev-state
529
+ * — even though setCardStatus dual-writes the real status to a2a_agent_cards
530
+ * (which `peers`/`discover` read correctly). Call after ensureA2ATables(db)
531
+ * before reading or transitioning a persisted card's status.
532
+ */
533
+ export function loadCardsFromDb(db) {
534
+ if (!db) return 0;
535
+ ensureA2ATables(db);
536
+ _v2Cards.clear();
537
+ const rows = db
538
+ .prepare(`SELECT id, status, updated_at FROM a2a_agent_cards`)
539
+ .all();
540
+ for (const r of rows) {
541
+ _v2Cards.set(r.id, {
542
+ cardId: r.id,
543
+ status: r.status || "active",
544
+ updatedAt: r.updated_at,
545
+ });
546
+ }
547
+ return _v2Cards.size;
548
+ }
549
+
526
550
  // ─── Task lifecycle V2 ───────────────────────────────────────────
527
551
 
528
552
  /**
@@ -62,6 +62,67 @@ export function ensureActivityPubTables(db) {
62
62
  `);
63
63
  }
64
64
 
65
+ /**
66
+ * Rehydrate _actors/_activities/_follows from the persisted ap_actors/
67
+ * ap_activities/ap_follows tables. The `cc` CLI runs every command in a fresh
68
+ * process, so without this the Maps start empty and an actor created / note
69
+ * published / follow made in a prior invocation is invisible (`cc ap actor
70
+ * list`/`outbox`/`followers`/`search` return nothing, and read paths first hit
71
+ * _requireActor against the empty _actors → "Actor not found"). Call after
72
+ * ensureActivityPubTables(db).
73
+ */
74
+ export function loadFromDb(db) {
75
+ if (!db) return 0;
76
+ _actors.clear();
77
+ _activities.clear();
78
+ _follows.clear();
79
+
80
+ const actorRows = db.prepare(`SELECT * FROM ap_actors`).all();
81
+ for (const row of actorRows) {
82
+ const id = row.id;
83
+ // Derived fields (type/preferredUsername/inbox/outbox/followers/following)
84
+ // are not persisted — reconstruct them from id exactly as createActor does.
85
+ _actors.set(id, {
86
+ id,
87
+ type: "Person",
88
+ username: row.username ?? null,
89
+ preferredUsername: row.username ?? null,
90
+ name: row.name ?? null,
91
+ summary: row.summary ?? null,
92
+ inbox: row.inbox_url ?? `${id}/inbox`,
93
+ outbox: row.outbox_url ?? `${id}/outbox`,
94
+ followers: `${id}/followers`,
95
+ following: `${id}/following`,
96
+ isLocal: !!row.is_local,
97
+ createdAt: row.created_at ?? null,
98
+ });
99
+ }
100
+
101
+ const activityRows = db.prepare(`SELECT * FROM ap_activities`).all();
102
+ for (const row of activityRows) {
103
+ let activity;
104
+ try {
105
+ activity = row.object_json ? JSON.parse(row.object_json) : null;
106
+ } catch {
107
+ activity = null;
108
+ }
109
+ if (!activity || !activity.id) continue; // can't reconstruct without it
110
+ _activities.set(activity.id, {
111
+ direction: row.direction,
112
+ ownerId: row.owner_id,
113
+ activity,
114
+ });
115
+ }
116
+
117
+ const followRows = db.prepare(`SELECT * FROM ap_follows`).all();
118
+ for (const row of followRows) {
119
+ const key = `${row.follower_id}|${row.followee_id}`;
120
+ _follows.set(key, { state: row.state, createdAt: row.created_at ?? null });
121
+ }
122
+
123
+ return _actors.size + _activities.size + _follows.size;
124
+ }
125
+
65
126
  /* ── Helpers ───────────────────────────────────────────────── */
66
127
 
67
128
  function _now() {
@@ -28,6 +28,7 @@ export {
28
28
  listBackgroundShellTasks,
29
29
  killBackgroundShellTask,
30
30
  killAllBackgroundShellTasks,
31
+ killAllBackgroundShellTasksSync,
31
32
  reapIdleBackgroundShellTasks,
32
33
  _ingestSearchOutput,
33
34
  writeFileVerified,
@@ -43,5 +44,6 @@ export {
43
44
  _anthropicThinkingParams,
44
45
  _normalizeAnthropicResponse,
45
46
  _resetFileFreshness,
47
+ _getSharedCodeIntel,
46
48
  disposeSharedCodeIntel,
47
49
  } from "../runtime/agent-core.js";
@@ -109,34 +109,58 @@ export function getBalance(agentId) {
109
109
  }
110
110
 
111
111
  export function pay(db, fromAgent, toAgent, amount, description) {
112
- if (amount <= 0) throw new Error("Amount must be positive");
112
+ if (!Number.isFinite(amount) || amount <= 0)
113
+ throw new Error("Amount must be positive");
113
114
 
114
115
  const fromBal = _getBalance(fromAgent);
115
116
  if (fromBal.balance < amount) {
116
117
  throw new Error(`Insufficient balance: ${fromBal.balance} < ${amount}`);
117
118
  }
118
119
 
119
- fromBal.balance -= amount;
120
120
  const toBal = _getBalance(toAgent);
121
+
122
+ // The ledger row, the debit and the credit must all land or none of them.
123
+ // Without a transaction a mid-way failure would debit the sender without
124
+ // crediting the receiver (tokens vanish); the CLI re-hydrates from these
125
+ // tables, so the loss would persist.
126
+ const fromSnap = { balance: fromBal.balance, locked: fromBal.locked };
127
+ const toSnap = { balance: toBal.balance, locked: toBal.locked };
128
+
129
+ fromBal.balance -= amount;
121
130
  toBal.balance += amount;
122
131
 
123
132
  const txId = crypto.randomUUID();
124
133
  const now = new Date().toISOString();
125
134
 
126
- db.prepare(
127
- `INSERT INTO economy_transactions (id, from_agent, to_agent, amount, type, description, created_at)
128
- VALUES (?, ?, ?, ?, ?, ?, ?)`,
129
- ).run(txId, fromAgent, toAgent, amount, "transfer", description || "", now);
135
+ const applyWrites = () => {
136
+ db.prepare(
137
+ `INSERT INTO economy_transactions (id, from_agent, to_agent, amount, type, description, created_at)
138
+ VALUES (?, ?, ?, ?, ?, ?, ?)`,
139
+ ).run(txId, fromAgent, toAgent, amount, "transfer", description || "", now);
130
140
 
131
- db.prepare(
132
- `INSERT OR REPLACE INTO economy_balances (agent_id, balance, locked, updated_at)
133
- VALUES (?, ?, ?, ?)`,
134
- ).run(fromAgent, fromBal.balance, fromBal.locked, now);
141
+ db.prepare(
142
+ `INSERT OR REPLACE INTO economy_balances (agent_id, balance, locked, updated_at)
143
+ VALUES (?, ?, ?, ?)`,
144
+ ).run(fromAgent, fromBal.balance, fromBal.locked, now);
135
145
 
136
- db.prepare(
137
- `INSERT OR REPLACE INTO economy_balances (agent_id, balance, locked, updated_at)
138
- VALUES (?, ?, ?, ?)`,
139
- ).run(toAgent, toBal.balance, toBal.locked, now);
146
+ db.prepare(
147
+ `INSERT OR REPLACE INTO economy_balances (agent_id, balance, locked, updated_at)
148
+ VALUES (?, ?, ?, ?)`,
149
+ ).run(toAgent, toBal.balance, toBal.locked, now);
150
+ };
151
+
152
+ try {
153
+ if (db && typeof db.transaction === "function") {
154
+ db.transaction(applyWrites)();
155
+ } else {
156
+ applyWrites();
157
+ }
158
+ } catch (err) {
159
+ // Roll the in-memory balances back to match the rolled-back DB.
160
+ Object.assign(fromBal, fromSnap);
161
+ Object.assign(toBal, toSnap);
162
+ throw err;
163
+ }
140
164
 
141
165
  return {
142
166
  txId,
@@ -158,6 +182,7 @@ export function openChannel(db, partyA, partyB, depositA) {
158
182
  );
159
183
  }
160
184
 
185
+ const balSnap = { balance: balA.balance, locked: balA.locked };
161
186
  if (deposit > 0) {
162
187
  balA.balance -= deposit;
163
188
  balA.locked += deposit;
@@ -174,12 +199,35 @@ export function openChannel(db, partyA, partyB, depositA) {
174
199
  status: "open",
175
200
  createdAt: now,
176
201
  };
177
- _channels.set(id, channel);
178
202
 
179
- db.prepare(
180
- `INSERT INTO economy_channels (id, party_a, party_b, balance_a, balance_b, status, created_at)
181
- VALUES (?, ?, ?, ?, ?, ?, ?)`,
182
- ).run(id, partyA, partyB, deposit, 0, "open", now);
203
+ // Persist the channel row AND the deposit debit together. Persisting only the
204
+ // channel (as before) left the locked deposit still fully available in
205
+ // economy_balances after the next process re-hydrates — double-counted, so a
206
+ // party could lock a deposit and still spend the same funds via pay().
207
+ const applyWrites = () => {
208
+ db.prepare(
209
+ `INSERT INTO economy_channels (id, party_a, party_b, balance_a, balance_b, status, created_at)
210
+ VALUES (?, ?, ?, ?, ?, ?, ?)`,
211
+ ).run(id, partyA, partyB, deposit, 0, "open", now);
212
+ if (deposit > 0) {
213
+ db.prepare(
214
+ `INSERT OR REPLACE INTO economy_balances (agent_id, balance, locked, updated_at)
215
+ VALUES (?, ?, ?, ?)`,
216
+ ).run(partyA, balA.balance, balA.locked, now);
217
+ }
218
+ };
219
+
220
+ try {
221
+ if (db && typeof db.transaction === "function") {
222
+ db.transaction(applyWrites)();
223
+ } else {
224
+ applyWrites();
225
+ }
226
+ _channels.set(id, channel);
227
+ } catch (err) {
228
+ Object.assign(balA, balSnap);
229
+ throw err;
230
+ }
183
231
 
184
232
  return channel;
185
233
  }
@@ -189,18 +237,49 @@ export function closeChannel(db, channelId) {
189
237
  if (!channel) throw new Error(`Channel not found: ${channelId}`);
190
238
  if (channel.status === "closed") throw new Error("Channel already closed");
191
239
 
192
- channel.status = "closed";
193
-
194
- // Settle: return balances to parties
195
240
  const balA = _getBalance(channel.partyA);
196
241
  const balB = _getBalance(channel.partyB);
242
+ const aSnap = { balance: balA.balance, locked: balA.locked };
243
+ const bSnap = { balance: balB.balance, locked: balB.locked };
244
+ const prevStatus = channel.status;
245
+
246
+ channel.status = "closed";
247
+ // Settle: return balances to parties.
197
248
  balA.balance += channel.balanceA;
198
249
  balA.locked = Math.max(0, balA.locked - channel.balanceA);
199
250
  balB.balance += channel.balanceB;
200
251
 
201
- db.prepare(`UPDATE economy_channels SET status = 'closed' WHERE id = ?`).run(
202
- channelId,
203
- );
252
+ const now = new Date().toISOString();
253
+ // Persist the settled balances alongside the status flip. Previously only the
254
+ // channel status was written, so the returned deposit was lost on re-hydrate.
255
+ const persistBal = (agentId, bal) =>
256
+ db
257
+ .prepare(
258
+ `INSERT OR REPLACE INTO economy_balances (agent_id, balance, locked, updated_at)
259
+ VALUES (?, ?, ?, ?)`,
260
+ )
261
+ .run(agentId, bal.balance, bal.locked, now);
262
+
263
+ const applyWrites = () => {
264
+ db.prepare(
265
+ `UPDATE economy_channels SET status = 'closed' WHERE id = ?`,
266
+ ).run(channelId);
267
+ persistBal(channel.partyA, balA);
268
+ if (channel.partyB !== channel.partyA) persistBal(channel.partyB, balB);
269
+ };
270
+
271
+ try {
272
+ if (db && typeof db.transaction === "function") {
273
+ db.transaction(applyWrites)();
274
+ } else {
275
+ applyWrites();
276
+ }
277
+ } catch (err) {
278
+ Object.assign(balA, aSnap);
279
+ Object.assign(balB, bSnap);
280
+ channel.status = prevStatus;
281
+ throw err;
282
+ }
204
283
 
205
284
  return { ...channel };
206
285
  }
@@ -257,9 +336,11 @@ export function getMarketListings(filter) {
257
336
  return listings;
258
337
  }
259
338
 
260
- export function tradeResource(listingId, buyer, quantity) {
339
+ export function tradeResource(db, listingId, buyer, quantity) {
261
340
  const listing = _market.get(listingId);
262
341
  if (!listing) throw new Error(`Listing not found: ${listingId}`);
342
+ if (!Number.isFinite(quantity) || quantity <= 0)
343
+ throw new Error("Quantity must be positive");
263
344
  if (listing.available < quantity) {
264
345
  throw new Error(
265
346
  `Insufficient availability: ${listing.available} < ${quantity}`,
@@ -272,13 +353,52 @@ export function tradeResource(listingId, buyer, quantity) {
272
353
  throw new Error(`Insufficient balance: ${buyerBal.balance} < ${cost}`);
273
354
  }
274
355
 
275
- buyerBal.balance -= cost;
276
356
  const sellerBal = _getBalance(listing.provider);
357
+ const buyerSnap = { balance: buyerBal.balance, locked: buyerBal.locked };
358
+ const sellerSnap = { balance: sellerBal.balance, locked: sellerBal.locked };
359
+ const listingSnap = { available: listing.available, status: listing.status };
360
+
361
+ buyerBal.balance -= cost;
277
362
  sellerBal.balance += cost;
278
363
  listing.available -= quantity;
279
-
280
364
  if (listing.available <= 0) listing.status = "sold_out";
281
365
 
366
+ const now = new Date().toISOString();
367
+ // Persist the money movement and the listing depletion. Previously this
368
+ // mutated only the in-memory Maps (the fn took no db at all), so a trade
369
+ // reported success but never survived the next process re-hydrate — the
370
+ // buyer was never charged, the seller never paid, and the listing never
371
+ // depleted (unlimited free re-purchases). Sibling listResource/pay persist.
372
+ const persistBal = (agentId, bal) =>
373
+ db
374
+ .prepare(
375
+ `INSERT OR REPLACE INTO economy_balances (agent_id, balance, locked, updated_at)
376
+ VALUES (?, ?, ?, ?)`,
377
+ )
378
+ .run(agentId, bal.balance, bal.locked, now);
379
+
380
+ const applyWrites = () => {
381
+ persistBal(buyer, buyerBal);
382
+ if (listing.provider !== buyer) persistBal(listing.provider, sellerBal);
383
+ db.prepare(
384
+ `UPDATE economy_market SET available = ?, status = ? WHERE id = ?`,
385
+ ).run(listing.available, listing.status, listingId);
386
+ };
387
+
388
+ try {
389
+ if (db && typeof db.transaction === "function") {
390
+ db.transaction(applyWrites)();
391
+ } else if (db) {
392
+ applyWrites();
393
+ }
394
+ } catch (err) {
395
+ // Roll the in-memory Maps back to match the rolled-back DB.
396
+ Object.assign(buyerBal, buyerSnap);
397
+ Object.assign(sellerBal, sellerSnap);
398
+ Object.assign(listing, listingSnap);
399
+ throw err;
400
+ }
401
+
282
402
  return { listingId, buyer, quantity, cost, remaining: listing.available };
283
403
  }
284
404
 
@@ -332,7 +452,8 @@ export function getContributions(agentId) {
332
452
  export function distributeRevenue(db, pool, agentIds) {
333
453
  if (!agentIds || agentIds.length === 0)
334
454
  throw new Error("No agents specified");
335
- if (pool <= 0) throw new Error("Pool must be positive");
455
+ if (!Number.isFinite(pool) || pool <= 0)
456
+ throw new Error("Pool must be positive");
336
457
 
337
458
  const share = pool / agentIds.length;
338
459
  const results = [];
@@ -364,6 +485,118 @@ export function _resetState() {
364
485
  _priceList.clear();
365
486
  }
366
487
 
488
+ /**
489
+ * Rehydrate the DB-backed in-memory Maps from the economy_* tables. The CLI runs
490
+ * each `cc economy` subcommand in a fresh node process, so these module-level
491
+ * Maps start empty every invocation. Every write dual-writes (Map + INSERT into
492
+ * economy_balances/channels/market/nfts/contributions) but every read
493
+ * (getBalance/getMarketListings/closeChannel/tradeResource/getContributions) is
494
+ * Map-only and nothing SELECTed the tables back — so `balance` read back 0, and
495
+ * `channel close`/`trade` threw "not found" for rows that genuinely exist on
496
+ * disk. Call after ensureEconomyTables(db).
497
+ *
498
+ * `_priceList` has no table and stays in-memory (out of scope).
499
+ */
500
+ export function loadFromDb(db) {
501
+ if (!db) return 0;
502
+ ensureEconomyTables(db);
503
+ _balances.clear();
504
+ _channels.clear();
505
+ _market.clear();
506
+ _nfts.clear();
507
+ _contributions.clear();
508
+
509
+ for (const r of db
510
+ .prepare(`SELECT agent_id, balance, locked FROM economy_balances`)
511
+ .all()) {
512
+ _balances.set(r.agent_id, {
513
+ balance: Number(r.balance) || 0,
514
+ locked: Number(r.locked) || 0,
515
+ });
516
+ }
517
+
518
+ for (const r of db
519
+ .prepare(
520
+ `SELECT id, party_a, party_b, balance_a, balance_b, status, created_at
521
+ FROM economy_channels ORDER BY created_at ASC`,
522
+ )
523
+ .all()) {
524
+ _channels.set(r.id, {
525
+ id: r.id,
526
+ partyA: r.party_a,
527
+ partyB: r.party_b,
528
+ balanceA: Number(r.balance_a) || 0,
529
+ balanceB: Number(r.balance_b) || 0,
530
+ status: r.status,
531
+ createdAt: r.created_at,
532
+ });
533
+ }
534
+
535
+ for (const r of db
536
+ .prepare(
537
+ `SELECT id, resource_type, provider, price, available, unit, status, created_at
538
+ FROM economy_market ORDER BY created_at ASC`,
539
+ )
540
+ .all()) {
541
+ _market.set(r.id, {
542
+ id: r.id,
543
+ resourceType: r.resource_type,
544
+ provider: r.provider,
545
+ price: Number(r.price),
546
+ available: Number(r.available) || 0,
547
+ unit: r.unit || "unit",
548
+ status: r.status,
549
+ createdAt: r.created_at,
550
+ });
551
+ }
552
+
553
+ for (const r of db
554
+ .prepare(
555
+ `SELECT id, owner, type, metadata, created_at FROM economy_nfts ORDER BY created_at ASC`,
556
+ )
557
+ .all()) {
558
+ // One corrupt metadata cell must not sink the whole NFT load.
559
+ let metadata = {};
560
+ try {
561
+ metadata = r.metadata ? JSON.parse(r.metadata) : {};
562
+ } catch {
563
+ metadata = {};
564
+ }
565
+ _nfts.set(r.id, {
566
+ id: r.id,
567
+ owner: r.owner,
568
+ type: r.type,
569
+ metadata,
570
+ createdAt: r.created_at,
571
+ });
572
+ }
573
+
574
+ for (const r of db
575
+ .prepare(
576
+ `SELECT id, agent_id, type, value, proof, created_at
577
+ FROM economy_contributions ORDER BY created_at ASC`,
578
+ )
579
+ .all()) {
580
+ if (!_contributions.has(r.agent_id)) _contributions.set(r.agent_id, []);
581
+ _contributions.get(r.agent_id).push({
582
+ id: r.id,
583
+ agentId: r.agent_id,
584
+ type: r.type,
585
+ value: Number(r.value) || 0,
586
+ proof: r.proof || "",
587
+ createdAt: r.created_at,
588
+ });
589
+ }
590
+
591
+ return (
592
+ _balances.size +
593
+ _channels.size +
594
+ _market.size +
595
+ _nfts.size +
596
+ _contributions.size
597
+ );
598
+ }
599
+
367
600
  export function _setBalance(agentId, balance, locked) {
368
601
  _balances.set(agentId, { balance, locked: locked || 0 });
369
602
  }
@@ -966,7 +966,13 @@ export function updateReputation(
966
966
  throw new Error(
967
967
  `Invalid dimension: ${dimension}. Expected one of ${REPUTATION_DIMENSIONS.join(",")}`,
968
968
  );
969
- const s = Math.max(MIN_REPUTATION, Math.min(MAX_REPUTATION, Number(score)));
969
+ // Reject non-finite scores: Math.max/min pass NaN straight through, so a
970
+ // non-numeric CLI arg (Number("abc") → NaN) would persist NaN (→ NULL) and
971
+ // corrupt every getReputation average + routeTask agent scoring.
972
+ const numericScore = Number(score);
973
+ if (!Number.isFinite(numericScore))
974
+ throw new Error("score must be a finite number");
975
+ const s = Math.max(MIN_REPUTATION, Math.min(MAX_REPUTATION, numericScore));
970
976
  const id = `rep:${_uuid()}`;
971
977
  const now = _now();
972
978
  db.prepare(