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
@@ -9,6 +9,7 @@ import { parseJsonOption } from "../lib/parse-json-option.js";
9
9
  import { bootstrap, shutdown } from "../runtime/bootstrap.js";
10
10
  import {
11
11
  ensureZKPTables,
12
+ loadFromDb as loadZkpFromDb,
12
13
  compileCircuit,
13
14
  generateProof,
14
15
  verifyProof,
@@ -64,6 +65,7 @@ export function registerZkpCommand(program) {
64
65
  }
65
66
  const db = ctx.db.getDatabase();
66
67
  ensureZKPTables(db);
68
+ loadZkpFromDb(db);
67
69
 
68
70
  const def = options.definition || "{}";
69
71
  const circuit = compileCircuit(db, name, def);
@@ -100,6 +102,7 @@ export function registerZkpCommand(program) {
100
102
  }
101
103
  const db = ctx.db.getDatabase();
102
104
  ensureZKPTables(db);
105
+ loadZkpFromDb(db);
103
106
 
104
107
  const privateInputs = parseJsonOption(options.private, "--private", {});
105
108
  const publicInputs = parseJsonOption(options.public, "--public", []);
@@ -142,6 +145,7 @@ export function registerZkpCommand(program) {
142
145
  }
143
146
  const db = ctx.db.getDatabase();
144
147
  ensureZKPTables(db);
148
+ loadZkpFromDb(db);
145
149
 
146
150
  const result = verifyProof(db, proofId);
147
151
  if (options.json) {
@@ -212,6 +216,7 @@ export function registerZkpCommand(program) {
212
216
  }
213
217
  const db = ctx.db.getDatabase();
214
218
  ensureZKPTables(db);
219
+ loadZkpFromDb(db);
215
220
 
216
221
  const stats = getZKPStats();
217
222
  if (options.json) {
@@ -266,6 +271,7 @@ export function registerZkpCommand(program) {
266
271
  }
267
272
  const db = ctx.db.getDatabase();
268
273
  ensureZKPTables(db);
274
+ loadZkpFromDb(db);
269
275
 
270
276
  const circuits = listCircuits(db);
271
277
  if (options.json) {
@@ -304,6 +310,7 @@ export function registerZkpCommand(program) {
304
310
  }
305
311
  const db = ctx.db.getDatabase();
306
312
  ensureZKPTables(db);
313
+ loadZkpFromDb(db);
307
314
 
308
315
  const proofs = listProofs(db, { circuitId: options.circuit });
309
316
  if (options.json) {
@@ -373,6 +380,7 @@ export function registerZkpCommand(program) {
373
380
  }
374
381
  const db = ctx.db.getDatabase();
375
382
  ensureZKPTables(db);
383
+ loadZkpFromDb(db);
376
384
 
377
385
  const result = setCircuitStatus(db, circuitId, status);
378
386
  logger.success(
@@ -402,6 +410,7 @@ export function registerZkpCommand(program) {
402
410
  }
403
411
  const db = ctx.db.getDatabase();
404
412
  ensureZKPTables(db);
413
+ loadZkpFromDb(db);
405
414
 
406
415
  const claims = parseJsonOption(options.claims, "--claims", {});
407
416
  const cred = registerCredential(db, {
@@ -444,6 +453,7 @@ export function registerZkpCommand(program) {
444
453
  }
445
454
  const db = ctx.db.getDatabase();
446
455
  ensureZKPTables(db);
456
+ loadZkpFromDb(db);
447
457
 
448
458
  const disclosed = fields
449
459
  .split(",")
@@ -497,6 +507,7 @@ export function registerZkpCommand(program) {
497
507
  }
498
508
  const db = ctx.db.getDatabase();
499
509
  ensureZKPTables(db);
510
+ loadZkpFromDb(db);
500
511
 
501
512
  const creds = listCredentials(db, { did: options.did });
502
513
  if (options.json) {
@@ -621,6 +632,7 @@ export function registerZkpCommand(program) {
621
632
  }
622
633
  const db = ctx.db.getDatabase();
623
634
  ensureZKPTables(db);
635
+ loadZkpFromDb(db);
624
636
  const def = parseJsonOption(options.definition, "--definition", {});
625
637
  const circuit = compileCircuitV2(db, {
626
638
  name,
@@ -648,6 +660,7 @@ export function registerZkpCommand(program) {
648
660
  const ctx = await bootstrap({ verbose: program.opts().verbose });
649
661
  const db = ctx.db.getDatabase();
650
662
  ensureZKPTables(db);
663
+ loadZkpFromDb(db);
651
664
  const patch = {};
652
665
  if (options.errorMessage !== undefined) {
653
666
  patch.errorMessage = options.errorMessage;
@@ -672,6 +685,7 @@ export function registerZkpCommand(program) {
672
685
  const ctx = await bootstrap({ verbose: program.opts().verbose });
673
686
  const db = ctx.db.getDatabase();
674
687
  ensureZKPTables(db);
688
+ loadZkpFromDb(db);
675
689
  const proof = generateProofV2(db, {
676
690
  circuitId,
677
691
  privateInputs: parseJsonOption(options.private, "--private"),
@@ -699,6 +713,7 @@ export function registerZkpCommand(program) {
699
713
  const ctx = await bootstrap({ verbose: program.opts().verbose });
700
714
  const db = ctx.db.getDatabase();
701
715
  ensureZKPTables(db);
716
+ loadZkpFromDb(db);
702
717
  const result = verifyProofV2(db, proofId);
703
718
  if (result.valid) {
704
719
  logger.success(`Proof ${proofId} VERIFIED`);
@@ -723,6 +738,7 @@ export function registerZkpCommand(program) {
723
738
  const ctx = await bootstrap({ verbose: program.opts().verbose });
724
739
  const db = ctx.db.getDatabase();
725
740
  ensureZKPTables(db);
741
+ loadZkpFromDb(db);
726
742
  failProof(db, proofId, { reason: options.reason });
727
743
  logger.success(`Proof ${proofId} → invalid`);
728
744
  await shutdown();
@@ -741,6 +757,7 @@ export function registerZkpCommand(program) {
741
757
  const ctx = await bootstrap({ verbose: program.opts().verbose });
742
758
  const db = ctx.db.getDatabase();
743
759
  ensureZKPTables(db);
760
+ loadZkpFromDb(db);
744
761
  const patch = {};
745
762
  if (options.errorMessage !== undefined) {
746
763
  patch.errorMessage = options.errorMessage;
@@ -762,6 +779,7 @@ export function registerZkpCommand(program) {
762
779
  const ctx = await bootstrap({ verbose: program.opts().verbose });
763
780
  const db = ctx.db.getDatabase();
764
781
  ensureZKPTables(db);
782
+ loadZkpFromDb(db);
765
783
  const expired = autoExpireProofs(db);
766
784
  logger.success(`Expired ${expired.length} proofs`);
767
785
  await shutdown();
@@ -792,6 +810,7 @@ export function registerZkpCommand(program) {
792
810
  const ctx = await bootstrap({ verbose: program.opts().verbose });
793
811
  const db = ctx.db.getDatabase();
794
812
  ensureZKPTables(db);
813
+ loadZkpFromDb(db);
795
814
  const disclosedFields = options.disclosed
796
815
  ? options.disclosed
797
816
  .split(",")
@@ -826,6 +845,7 @@ export function registerZkpCommand(program) {
826
845
  const ctx = await bootstrap({ verbose: program.opts().verbose });
827
846
  const db = ctx.db.getDatabase();
828
847
  ensureZKPTables(db);
848
+ loadZkpFromDb(db);
829
849
  const stats = getZKPStatsV2();
830
850
  console.log(JSON.stringify(stats, null, 2));
831
851
  await shutdown();
@@ -19,6 +19,52 @@ import {
19
19
  handleRemoteSessionPushRegister,
20
20
  handleRemoteSessionRevoke,
21
21
  } from "./remote-session-protocol.js";
22
+ import { RemoteCommandLedger } from "../../harness/remote-command-ledger.js";
23
+
24
+ /**
25
+ * Reconnect-safe command execution. When a message carries a stable
26
+ * `commandId`, route it through the server's RemoteCommandLedger so the side
27
+ * effect runs AT MOST ONCE: a client that re-sends the same command after a
28
+ * dropped ACK / reconnect gets a `replayed` ack instead of a second execution
29
+ * (Phase 5 acceptance "断网恢复后不会重复执行工具调用"). Messages WITHOUT a
30
+ * commandId are unchanged — they call `_executeCommand` directly, so existing
31
+ * clients behave exactly as before. A revoked device / stale-seq command is
32
+ * rejected without executing.
33
+ */
34
+ async function executeWithIdempotency(server, id, ws, message, stream) {
35
+ const commandId = message.commandId;
36
+ if (!commandId) {
37
+ return server._executeCommand(id, ws, message.command, stream);
38
+ }
39
+ // Create the ledger SYNCHRONOUSLY (no await between the check and the assign)
40
+ // so two concurrent re-deliveries of the same commandId share ONE ledger and
41
+ // coalesce; a lazy `await import()` here would let each build its own ledger
42
+ // and both would execute — the exact double-exec this guards against.
43
+ if (!server._commandLedger) {
44
+ server._commandLedger = new RemoteCommandLedger();
45
+ }
46
+ const outcome = await server._commandLedger.apply(
47
+ { commandId, deviceId: message.deviceId ?? null, seq: message.seq },
48
+ () => server._executeCommand(id, ws, message.command, stream),
49
+ );
50
+ if (outcome.status === "replayed") {
51
+ server._send(ws, {
52
+ id,
53
+ type: "replayed",
54
+ commandId,
55
+ applyIndex: outcome.applyIndex,
56
+ });
57
+ } else if (outcome.status === "rejected") {
58
+ server._send(ws, {
59
+ id,
60
+ type: "error",
61
+ code: "COMMAND_REJECTED",
62
+ commandId,
63
+ message: outcome.reason,
64
+ });
65
+ }
66
+ return outcome;
67
+ }
22
68
 
23
69
  export function createWsMessageDispatcher(server) {
24
70
  return {
@@ -52,8 +98,8 @@ export function createWsMessageDispatcher(server) {
52
98
  auth: () => server._handleAuth(clientId, ws, message),
53
99
  ping: () =>
54
100
  server._send(ws, { id, type: "pong", serverTime: Date.now() }),
55
- execute: () => server._executeCommand(id, ws, message.command, false),
56
- stream: () => server._executeCommand(id, ws, message.command, true),
101
+ execute: () => executeWithIdempotency(server, id, ws, message, false),
102
+ stream: () => executeWithIdempotency(server, id, ws, message, true),
57
103
  cancel: () => server._cancelRequest(id, ws),
58
104
  "session-create": () => server._handleSessionCreate(id, ws, message),
59
105
  "session-resume": () => server._handleSessionResume(id, ws, message),
@@ -7,6 +7,7 @@ import {
7
7
  RemoteSessionCryptoContext,
8
8
  createRemotePairingUri,
9
9
  } from "../../harness/remote-session-crypto.js";
10
+ import { RemoteCommandLedger } from "../../harness/remote-command-ledger.js";
10
11
 
11
12
  const CLIENT_EVENT_SCOPES = Object.freeze({
12
13
  prompt: "prompt",
@@ -22,6 +23,55 @@ function audit(server, entry) {
22
23
  server.remoteSessionAudit?.record(entry);
23
24
  }
24
25
 
26
+ /**
27
+ * Apply a remote-client control event (prompt / approval.resolve / interrupt)
28
+ * idempotently when it carries a stable `commandId`. This is the ACTUAL takeover
29
+ * path — a paired mobile/web device driving the host agent — and it does NOT
30
+ * flow through message-dispatcher's execute/stream ledger, so without this a
31
+ * prompt re-sent after a dropped connection would run the agent turn a SECOND
32
+ * time (Phase 5 acceptance "断网恢复后不会重复执行工具调用"). The side effect
33
+ * (audit + dispatch into the host session) runs AT MOST ONCE per commandId; a
34
+ * re-delivery gets a `replayed` ack instead. Byte-identical when the event
35
+ * carries no `commandId` (existing clients unchanged). deviceId is the
36
+ * AUTHENTICATED clientId, so a device can never spoof another's idempotency /
37
+ * ordering stream. A revoked device / stale seq is rejected without forwarding.
38
+ * Uses a ledger SEPARATE from the execute/stream one (`_commandLedger`) so the
39
+ * two paths keep independent per-device sequence spaces.
40
+ */
41
+ async function applyControlIdempotent(server, clientId, ws, message, forward) {
42
+ const commandId = message.commandId;
43
+ if (!commandId) return forward();
44
+ // Create the ledger SYNCHRONOUSLY (no await between the check and the assign)
45
+ // so two concurrent re-deliveries of the same commandId share ONE ledger and
46
+ // coalesce — a lazy `await import()` here would let each build its own ledger
47
+ // and both would execute, defeating the whole guarantee.
48
+ if (!server._remoteControlLedger) {
49
+ server._remoteControlLedger = new RemoteCommandLedger();
50
+ }
51
+ const outcome = await server._remoteControlLedger.apply(
52
+ { commandId, deviceId: clientId, seq: message.seq },
53
+ async () => {
54
+ await forward();
55
+ return true;
56
+ },
57
+ );
58
+ if (outcome.status === "replayed") {
59
+ reply(server, ws, message.id, "remote-session-published", {
60
+ delivered: 0,
61
+ replayed: true,
62
+ commandId,
63
+ applyIndex: outcome.applyIndex,
64
+ });
65
+ } else if (outcome.status === "rejected") {
66
+ reply(server, ws, message.id, "error", {
67
+ code: "COMMAND_REJECTED",
68
+ commandId,
69
+ message: outcome.reason,
70
+ });
71
+ }
72
+ return outcome;
73
+ }
74
+
25
75
  function attachPairingUri(server, result) {
26
76
  const relayUrl = server.remoteSessionRelayUrl;
27
77
  const hostPeerId = server.remoteSessionPeerId;
@@ -341,6 +391,43 @@ export async function handleRemoteSessionPublish(
341
391
  if (!message.event || typeof message.event.type !== "string") {
342
392
  throw new Error("event.type is required");
343
393
  }
394
+ // A paired device (incl. relay-only mobiles) refreshing its own vendor push
395
+ // token — e.g. after FCM onNewToken. Self-scoped: authorize proves
396
+ // membership and registerPush keys off the authenticated clientId, so a
397
+ // device can only ever set its OWN token. Omitting the token clears it.
398
+ if (message.event.type === "push.register") {
399
+ server.remoteSessions.authorize(
400
+ message.remoteSessionId,
401
+ clientId,
402
+ "observe",
403
+ );
404
+ const registered = server.remoteSessions.registerPush(
405
+ message.remoteSessionId,
406
+ clientId,
407
+ {
408
+ token: message.event.pushToken,
409
+ provider: message.event.pushProvider,
410
+ },
411
+ );
412
+ audit(server, {
413
+ sessionId: message.remoteSessionId,
414
+ actor: clientId,
415
+ action: "push.registered",
416
+ detail: {
417
+ hasPush: registered.hasPush,
418
+ provider: registered.provider,
419
+ via: "relay",
420
+ },
421
+ });
422
+ reply(
423
+ server,
424
+ ws,
425
+ message.id,
426
+ "remote-session-push-registered",
427
+ registered,
428
+ );
429
+ return;
430
+ }
344
431
  const requiredScope = CLIENT_EVENT_SCOPES[message.event.type];
345
432
  const { session } = server.remoteSessions.authorize(
346
433
  message.remoteSessionId,
@@ -358,49 +445,60 @@ export async function handleRemoteSessionPublish(
358
445
  id: message.id,
359
446
  sessionId: session.agentSessionId,
360
447
  };
361
- if (message.event.type === "prompt") {
362
- if (
363
- typeof message.event.content !== "string" ||
364
- !message.event.content.trim()
365
- ) {
366
- throw new Error("prompt content is required");
367
- }
368
- // Record the shape, not the content — the audit trail must stay useful
369
- // without hoarding potentially sensitive session prompts.
370
- audit(server, {
371
- sessionId: message.remoteSessionId,
372
- actor: clientId,
373
- action: "control.prompt",
374
- detail: { chars: message.event.content.length },
375
- });
376
- handleSessionMessage(server, message.id, ws, {
377
- ...controlMessage,
378
- content: message.event.content,
379
- });
380
- } else if (message.event.type === "approval.resolve") {
381
- audit(server, {
382
- sessionId: message.remoteSessionId,
383
- actor: clientId,
384
- action: "control.approval",
385
- detail: {
386
- requestId: message.event.requestId || message.event.approvalId,
387
- approved: message.event.answer ?? message.event.approved,
388
- },
389
- });
390
- await handleSessionAnswer(server, message.id, ws, {
391
- ...controlMessage,
392
- requestId: message.event.requestId || message.event.approvalId,
393
- answer: message.event.answer ?? message.event.approved,
394
- });
395
- } else if (message.event.type === "interrupt") {
396
- audit(server, {
397
- sessionId: message.remoteSessionId,
398
- actor: clientId,
399
- action: "control.interrupt",
400
- detail: null,
401
- });
402
- await handleSessionInterrupt(server, message.id, ws, controlMessage);
448
+ // Validate up-front so a malformed control event errors identically
449
+ // whether or not it carries a commandId — idempotency must never change
450
+ // validation semantics (a bad prompt must not consume a commandId slot).
451
+ if (
452
+ message.event.type === "prompt" &&
453
+ (typeof message.event.content !== "string" ||
454
+ !message.event.content.trim())
455
+ ) {
456
+ throw new Error("prompt content is required");
403
457
  }
458
+ // Idempotent forward: a control event with a stable commandId runs its
459
+ // side effect (audit + dispatch into the host agent) AT MOST ONCE, so a
460
+ // reconnecting device re-sending the same prompt/approval/interrupt gets a
461
+ // `replayed` ack instead of a second agent turn. No commandId → forwarded
462
+ // directly, byte-identical to before.
463
+ await applyControlIdempotent(server, clientId, ws, message, async () => {
464
+ if (message.event.type === "prompt") {
465
+ // Record the shape, not the content — the audit trail must stay
466
+ // useful without hoarding potentially sensitive session prompts.
467
+ audit(server, {
468
+ sessionId: message.remoteSessionId,
469
+ actor: clientId,
470
+ action: "control.prompt",
471
+ detail: { chars: message.event.content.length },
472
+ });
473
+ handleSessionMessage(server, message.id, ws, {
474
+ ...controlMessage,
475
+ content: message.event.content,
476
+ });
477
+ } else if (message.event.type === "approval.resolve") {
478
+ audit(server, {
479
+ sessionId: message.remoteSessionId,
480
+ actor: clientId,
481
+ action: "control.approval",
482
+ detail: {
483
+ requestId: message.event.requestId || message.event.approvalId,
484
+ approved: message.event.answer ?? message.event.approved,
485
+ },
486
+ });
487
+ await handleSessionAnswer(server, message.id, ws, {
488
+ ...controlMessage,
489
+ requestId: message.event.requestId || message.event.approvalId,
490
+ answer: message.event.answer ?? message.event.approved,
491
+ });
492
+ } else if (message.event.type === "interrupt") {
493
+ audit(server, {
494
+ sessionId: message.remoteSessionId,
495
+ actor: clientId,
496
+ action: "control.interrupt",
497
+ detail: null,
498
+ });
499
+ await handleSessionInterrupt(server, message.id, ws, controlMessage);
500
+ }
501
+ });
404
502
  return;
405
503
  }
406
504
 
@@ -37,7 +37,7 @@ import {
37
37
  RemoteSessionPushDispatcher,
38
38
  isApprovalRequestEvent,
39
39
  } from "../../harness/remote-session-push.js";
40
- import { createRemoteSessionPushSender } from "../../harness/remote-session-push-fcm.js";
40
+ import { createRemoteSessionPushSender } from "../../harness/remote-session-push-senders.js";
41
41
  import { RemoteSessionRelay } from "../remote-session-relay.js";
42
42
  import { handleRemoteSessionPublish } from "./remote-session-protocol.js";
43
43
  import { handleTaskDetail, handleTaskHistory } from "./task-protocol.js";
@@ -438,12 +438,19 @@ function performLegacySessionMigration(sourcePath, options) {
438
438
  }
439
439
 
440
440
  const validation = validateJsonlSession(sessionId);
441
- if (
442
- !validation.valid ||
443
- validation.messageCount !== legacy.messages.length
444
- ) {
441
+ // Verify EVERY legacy message persisted, by event count — NOT by
442
+ // `messageCount`, which counts only user_message/assistant_message events.
443
+ // A legacy `system` message becomes a `system` event and a `tool` message a
444
+ // `tool_result` event (see appendLegacyMessage); neither is a "message" by
445
+ // that count, so comparing messageCount to legacy.messages.length wrongly
446
+ // FAILED migration for any session with a system prompt or tool call.
447
+ // appendLegacyMessage writes exactly one event per message, plus the leading
448
+ // session_start and an optional trailing summary event.
449
+ const expectedEvents =
450
+ 1 + legacy.messages.length + (legacy.summary ? 1 : 0);
451
+ if (!validation.valid || validation.eventCount !== expectedEvents) {
445
452
  throw new Error(
446
- `post-migration validation failed for ${sessionId} (${validation.messageCount}/${legacy.messages.length} messages)`,
453
+ `post-migration validation failed for ${sessionId} (${validation.eventCount}/${expectedEvents} events)`,
447
454
  );
448
455
  }
449
456
 
@@ -11,6 +11,7 @@ import crypto from "crypto";
11
11
  import fs from "fs";
12
12
  import path from "path";
13
13
  import { getElectronUserDataDir } from "../lib/paths.js";
14
+ import { escapeLike } from "../lib/sql-like.js";
14
15
 
15
16
  /**
16
17
  * Ensure plugin tables exist.
@@ -288,11 +289,15 @@ export function registerInMarketplace(db, pluginInfo) {
288
289
  */
289
290
  export function searchRegistry(db, query) {
290
291
  ensurePluginTables(db);
292
+ // Escape LIKE metacharacters so a query containing % or _ is matched
293
+ // literally — otherwise `cc plugin search "%"` (or any term with _) is treated
294
+ // as a wildcard and matches EVERY registry row instead of the intended text.
295
+ const pattern = `%${escapeLike(query)}%`;
291
296
  return db
292
297
  .prepare(
293
- "SELECT * FROM plugin_registry WHERE name LIKE ? OR description LIKE ? ORDER BY downloads DESC",
298
+ "SELECT * FROM plugin_registry WHERE name LIKE ? ESCAPE '\\' OR description LIKE ? ESCAPE '\\' ORDER BY downloads DESC",
294
299
  )
295
- .all(`%${query}%`, `%${query}%`);
300
+ .all(pattern, pattern);
296
301
  }
297
302
 
298
303
  /**
@@ -352,7 +357,11 @@ export function installPluginSkills(db, pluginName, pluginPath, skills) {
352
357
  const installed = [];
353
358
 
354
359
  for (const skill of skills) {
355
- if (!skill || typeof skill.name !== "string" || typeof skill.path !== "string") {
360
+ if (
361
+ !skill ||
362
+ typeof skill.name !== "string" ||
363
+ typeof skill.path !== "string"
364
+ ) {
356
365
  continue;
357
366
  }
358
367
  const srcDir = path.resolve(pluginPath, skill.path);
@@ -363,7 +372,10 @@ export function installPluginSkills(db, pluginName, pluginPath, skills) {
363
372
  if (!fs.existsSync(srcDir)) continue;
364
373
 
365
374
  const destDir = path.join(marketplaceDir, skill.name);
366
- if (!_isWithin(marketplaceDir, destDir) || path.resolve(destDir) === path.resolve(marketplaceDir)) {
375
+ if (
376
+ !_isWithin(marketplaceDir, destDir) ||
377
+ path.resolve(destDir) === path.resolve(marketplaceDir)
378
+ ) {
367
379
  continue;
368
380
  }
369
381
  fs.mkdirSync(destDir, { recursive: true });
@@ -251,8 +251,25 @@ export class PromptCompressor {
251
251
  };
252
252
  }
253
253
 
254
+ // Pinned facts — a DETERMINISTIC fact-retention guarantee. A message marked
255
+ // `pinned:true` (or matched by an `options.isPinned` predicate) MUST survive
256
+ // compaction verbatim regardless of any strategy or the non-deterministic LLM
257
+ // summary. Every other retention here is positional (system / recent-N / last
258
+ // user) or summary-dependent, so an important fact that scrolls out of the
259
+ // recent window would otherwise survive only if the summary happens to keep
260
+ // it. We pull pins out BEFORE any strategy runs (so nothing can drop them),
261
+ // then re-insert them as a sticky block right after the system messages.
262
+ const isPinned =
263
+ typeof options.isPinned === "function"
264
+ ? options.isPinned
265
+ : (m) => m && (m.pinned === true || m._pin === true);
266
+ const pinned = messages.filter((m) => isPinned(m));
267
+ const working = pinned.length
268
+ ? messages.filter((m) => !isPinned(m))
269
+ : messages;
270
+
254
271
  const originalTokens = estimateMessagesTokens(messages);
255
- let result = [...messages];
272
+ let result = [...working];
256
273
  const applied = [];
257
274
 
258
275
  if (feature("CONTEXT_SNIP")) {
@@ -288,6 +305,15 @@ export class PromptCompressor {
288
305
  }
289
306
  }
290
307
 
308
+ // Re-insert pinned facts verbatim (order preserved) right after the leading
309
+ // system messages, so they end up as a sticky facts block at the top.
310
+ if (pinned.length) {
311
+ const sys = result.filter((m) => m.role === "system");
312
+ const nonSys = result.filter((m) => m.role !== "system");
313
+ result = [...sys, ...pinned, ...nonSys];
314
+ applied.push("pinned");
315
+ }
316
+
291
317
  // Tool-pair repair (opt-in) — callers compacting tool-laden histories
292
318
  // (e.g. the headless agent loop) pass this so truncation/snip never leaves
293
319
  // an orphaned tool result or unanswered tool_call for a strict API.