chainlesschain 0.162.149 → 0.162.151

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 (285) hide show
  1. package/README.md +1 -1
  2. package/package.json +3 -2
  3. package/src/assets/web-panel/assets/{AIOps-BJif14yR.js → AIOps-DuEOzebi.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-CXek6gJY.js → ActionButton-C6GiJa5H.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-BgQhdAJi.js → Analytics-BBIiL_pO.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-DTYl5NtR.js → AppLayout-CuI2gZRy.js} +3 -3
  7. package/src/assets/web-panel/assets/{Audit-BzATQAeR.js → Audit-CbUjfr-K.js} +1 -1
  8. package/src/assets/web-panel/assets/{Backup-BzdPEQhL.js → Backup-CsSW9ljf.js} +1 -1
  9. package/src/assets/web-panel/assets/{BaseInput-BM0KVh8E.js → BaseInput-kM3rLe7F.js} +1 -1
  10. package/src/assets/web-panel/assets/{Chat-D7fHXHkz.js → Chat-kfE51YN3.js} +4 -4
  11. package/src/assets/web-panel/assets/{ChatBubbleRenderer-Wm34RR-b.js → ChatBubbleRenderer-Bg2FTW6A.js} +1 -1
  12. package/src/assets/web-panel/assets/{Checkbox-CAiSQ9vO.js → Checkbox-jYb1uj-M.js} +1 -1
  13. package/src/assets/web-panel/assets/{Codegen-Df40CrEe.js → Codegen-X9XiD5Lj.js} +1 -1
  14. package/src/assets/web-panel/assets/{Col-DIT2fNFU.js → Col-BfbHu1xI.js} +1 -1
  15. package/src/assets/web-panel/assets/{Community-CSTIbW2k.js → Community-c4oJMFS-.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compact-DtqXZZUi.js → Compact-BFmnZpH7.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compliance-CUtzw6o7.js → Compliance-s9shVHBS.js} +1 -1
  18. package/src/assets/web-panel/assets/{Cowork-CezmlnmU.js → Cowork-C5da--TC.js} +2 -2
  19. package/src/assets/web-panel/assets/{Cron-P4BITarg.js → Cron-9kNbyNE4.js} +2 -2
  20. package/src/assets/web-panel/assets/{Crosschain-BRRiYwvq.js → Crosschain-C1k3NJD4.js} +1 -1
  21. package/src/assets/web-panel/assets/{DID-L5ijB9i4.js → DID-DkheEvNK.js} +2 -2
  22. package/src/assets/web-panel/assets/{Dashboard-CFxro4ob.js → Dashboard-C3FuSGmJ.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dropdown-BmAFCQ71.js → Dropdown-CAV6FMFD.js} +1 -1
  24. package/src/assets/web-panel/assets/{EmailListRenderer-DJBCEuon.js → EmailListRenderer-Cc-Ulc4l.js} +1 -1
  25. package/src/assets/web-panel/assets/{FamilyGuardDashboard-z4oLq6eT.js → FamilyGuardDashboard-8CitHEtv.js} +1 -1
  26. package/src/assets/web-panel/assets/{Federation-DsVCpHMF.js → Federation-DFSZ5KDt.js} +1 -1
  27. package/src/assets/web-panel/assets/{FormItemContext-DP3bP5th.js → FormItemContext-CEWCtnG2.js} +1 -1
  28. package/src/assets/web-panel/assets/{GenericCardRenderer-BAXP2Gc6.js → GenericCardRenderer-CwRzNzmX.js} +1 -1
  29. package/src/assets/web-panel/assets/{Git-I3g_bAw9.js → Git-0rgDM7cJ.js} +2 -2
  30. package/src/assets/web-panel/assets/{Governance-jHS5-ioS.js → Governance-CfBKtK9F.js} +1 -1
  31. package/src/assets/web-panel/assets/{Inference-CPL7sfx9.js → Inference-CzcUVvud.js} +1 -1
  32. package/src/assets/web-panel/assets/{KnowledgeGraph-Jf236h4C.js → KnowledgeGraph-Dwc4YL4A.js} +1 -1
  33. package/src/assets/web-panel/assets/{Logs-Cm2tcSKg.js → Logs-DgFPwR2F.js} +2 -2
  34. package/src/assets/web-panel/assets/{Marketplace-CZK82rhi.js → Marketplace-DnpPTbGU.js} +1 -1
  35. package/src/assets/web-panel/assets/{McpTools-CZCeji7a.js → McpTools-DRxxINyW.js} +4 -4
  36. package/src/assets/web-panel/assets/{Memory-3l2KVS9k.js → Memory-OhmW_6Z3.js} +2 -2
  37. package/src/assets/web-panel/assets/{MobileBridge-VYdpoLh6.js → MobileBridge-DkTW-RK5.js} +1 -1
  38. package/src/assets/web-panel/assets/{MobileProjects-CiB9cmm1.js → MobileProjects-DpCGV_lI.js} +1 -1
  39. package/src/assets/web-panel/assets/{Mtc-wCFZbBuL.js → Mtc--vmkL0AS.js} +2 -2
  40. package/src/assets/web-panel/assets/{MtcAudit-1a3THIyG.js → MtcAudit-DGoFWjD4.js} +4 -4
  41. package/src/assets/web-panel/assets/{Multisig-DMzLB2hG.js → Multisig-B4kWgq95.js} +3 -3
  42. package/src/assets/web-panel/assets/{NLProgramming-D9wZbf6l.js → NLProgramming-YQwvommE.js} +1 -1
  43. package/src/assets/web-panel/assets/{Notes-hrFe2ZM-.js → Notes-CgjtUADJ.js} +3 -3
  44. package/src/assets/web-panel/assets/{NotificationSettings-CHGX5Jwm.js → NotificationSettings-6JDrpBG5.js} +1 -1
  45. package/src/assets/web-panel/assets/OrderTableRenderer-PM6IlxjO.js +1 -0
  46. package/src/assets/web-panel/assets/{Organization-By7FkhtY.js → Organization-8McOT_OF.js} +4 -4
  47. package/src/assets/web-panel/assets/{Overflow--khGSzJn.js → Overflow-DAZpSCGc.js} +1 -1
  48. package/src/assets/web-panel/assets/{P2P-CAG9dH35.js → P2P-B7l2ZWLy.js} +2 -2
  49. package/src/assets/web-panel/assets/{PdhVaultBrowser-B3SQZmK9.js → PdhVaultBrowser-W1Ud-NAL.js} +3 -3
  50. package/src/assets/web-panel/assets/{Permissions-D35ec6JA.js → Permissions-Czm_w9u_.js} +4 -4
  51. package/src/assets/web-panel/assets/{PersonalDataHub-CxBF7hW_.js → PersonalDataHub-B4F0_ZVM.js} +2 -2
  52. package/src/assets/web-panel/assets/{Pipeline-s6EtOO1s.js → Pipeline-B37aFiWv.js} +1 -1
  53. package/src/assets/web-panel/assets/{Privacy-BbJYmWmO.js → Privacy-94KBnRrD.js} +1 -1
  54. package/src/assets/web-panel/assets/{ProjectInit-VGQq1jMT.js → ProjectInit-B5h8_dlh.js} +2 -2
  55. package/src/assets/web-panel/assets/{ProjectSettings-B1ew3Teh.js → ProjectSettings-lmeI3Lpm.js} +2 -2
  56. package/src/assets/web-panel/assets/Projects-D5AYOasl.js +1 -0
  57. package/src/assets/web-panel/assets/{Providers-mrO47FIK.js → Providers-B3cNWwJg.js} +1 -1
  58. package/src/assets/web-panel/assets/{QrScannerModal-IJF2mHyw.js → QrScannerModal-CHRvOw1R.js} +1 -1
  59. package/src/assets/web-panel/assets/{QuickAsk-CU0wN_Z0.js → QuickAsk-D1JMgFEd.js} +1 -1
  60. package/src/assets/web-panel/assets/{Recommend-DhN37R6G.js → Recommend-EYWGR79p.js} +1 -1
  61. package/src/assets/web-panel/assets/{RemoteSession-D_xOX_hu.js → RemoteSession-BAMC2pJt.js} +2 -2
  62. package/src/assets/web-panel/assets/{Reputation-D_Ssv7uH.js → Reputation-X2Hk1XG_.js} +1 -1
  63. package/src/assets/web-panel/assets/{Row-Kx5dKxX7.js → Row-Eq98LRtU.js} +1 -1
  64. package/src/assets/web-panel/assets/{RssFeed-BlGwqZkY.js → RssFeed-i76s6z_o.js} +2 -2
  65. package/src/assets/web-panel/assets/{Search-hLFQzxpb.js → Search-D_Es7CAI.js} +1 -1
  66. package/src/assets/web-panel/assets/{Security-DMlvsVt4.js → Security-kayD2e94.js} +3 -3
  67. package/src/assets/web-panel/assets/{Services-Bd0Qsj2m.js → Services-Ctsm6ul8.js} +2 -2
  68. package/src/assets/web-panel/assets/{Skeleton-DFclq9X3.js → Skeleton-CRNYlfdf.js} +1 -1
  69. package/src/assets/web-panel/assets/{Skills-BNtln2qY.js → Skills-DkZYpF4-.js} +1 -1
  70. package/src/assets/web-panel/assets/{Sla-Dch5H19G.js → Sla-DXkoBcOP.js} +1 -1
  71. package/src/assets/web-panel/assets/{SpeechSettings-2UfQcU1g.js → SpeechSettings-DXi_GI1d.js} +1 -1
  72. package/src/assets/web-panel/assets/{SyncSettings-CD9YQr4i.js → SyncSettings-rNKpfomn.js} +2 -2
  73. package/src/assets/web-panel/assets/{Tasks-BNu-7MzI.js → Tasks-XF4uPtG-.js} +1 -1
  74. package/src/assets/web-panel/assets/{Templates-D1n9CaIR.js → Templates-i0Hzfeyu.js} +1 -1
  75. package/src/assets/web-panel/assets/{Tenant-DenL3iBW.js → Tenant-sMpHAi27.js} +1 -1
  76. package/src/assets/web-panel/assets/Terminal-BoZvaYAl.js +3 -0
  77. package/src/assets/web-panel/assets/{TimelineRenderer-D87IfukO.js → TimelineRenderer-yuC6K7Rf.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tokens-BkiZc8E3.js → Tokens-B8O8i0s6.js} +1 -1
  79. package/src/assets/web-panel/assets/{Trigger-BNRSytGN.js → Trigger-Bv6yrlCr.js} +1 -1
  80. package/src/assets/web-panel/assets/{Trust-Bwbd4X2m.js → Trust-C4mW95Ev.js} +1 -1
  81. package/src/assets/web-panel/assets/{UkeySign-B8O2bs0o.js → UkeySign-DV6yKaHn.js} +1 -1
  82. package/src/assets/web-panel/assets/{VideoEditing-C2fL8zmH.js → VideoEditing-UI479-sD.js} +1 -1
  83. package/src/assets/web-panel/assets/{Wallet-BORYDdE1.js → Wallet-M5oV9EVP.js} +4 -4
  84. package/src/assets/web-panel/assets/{WebAuthn-C0V5S2FM.js → WebAuthn-DDyDHPDR.js} +4 -4
  85. package/src/assets/web-panel/assets/{WorkflowEditor-2dR0fcHL.js → WorkflowEditor-RoBv4rqk.js} +1 -1
  86. package/src/assets/web-panel/assets/{chat-BmuAFAn8.js → chat-Cw1mE5LS.js} +1 -1
  87. package/src/assets/web-panel/assets/{colors-CN3smMcK.js → colors-BFP62Gwf.js} +1 -1
  88. package/src/assets/web-panel/assets/{compact-item-DCnxb4kW.js → compact-item-17HL6pyC.js} +1 -1
  89. package/src/assets/web-panel/assets/{createContext-vlR43pHn.js → createContext-D55X4fZX.js} +1 -1
  90. package/src/assets/web-panel/assets/devWarning-CqbHYuRc.js +1 -0
  91. package/src/assets/web-panel/assets/{hasIn-D04tHYFd.js → hasIn-D3E5mNsP.js} +1 -1
  92. package/src/assets/web-panel/assets/{index-DbVsQBOH.js → index--44J50mc.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-TslMTwNy.js → index-ASPYTzMK.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-CTOCnIQ7.js → index-BC6zxOlU.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-ljuBiQW9.js → index-BEa1RW4c.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-jzR7Ujuw.js → index-BQmZg5si.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-BudvKQfG.js → index-BY_xZ2jy.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-CP9m9Ggr.js → index-BgN5G5vF.js} +3 -3
  99. package/src/assets/web-panel/assets/{index-Cr-A0FYJ.js → index-BnGpft-Z.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-D5LZVZ0L.js → index-Bq83UBDr.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-ToUh2b1-.js → index-Bzpp2z2S.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DbADHwhr.js → index-CFYGn88j.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-ClhAHDK3.js → index-CGyTos4p.js} +1 -1
  104. package/src/assets/web-panel/assets/index-CKBI1U5K.js +1 -0
  105. package/src/assets/web-panel/assets/{index-C-6NO5il.js → index-CLEzsZ8A.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-D8vwp4qp.js → index-CR9rNUvi.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-_FIkN3jd.js → index-CW6LLoJO.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-D65_XseV.js → index-C_MfcrLf.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-CnXebZLL.js → index-Cdvk2_2q.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-D_n8_vfI.js → index-CjCwi7we.js} +1 -1
  111. package/src/assets/web-panel/assets/index-CkLp6DTO.js +1 -0
  112. package/src/assets/web-panel/assets/{index-DDwLgQY9.js → index-CvCFKojj.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-430S68MN.js → index-D4LHSde4.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-BXRg8GFQ.js → index-DCLu84x-.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DTtRscUa.js → index-DD_qGBrt.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-BasvsWDM.js → index-DIRvdwBX.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BeGDEXFs.js → index-DOjA8bvj.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CsAsCPJ6.js → index-Da27u6j0.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-D28DeAAB.js → index-DkBVYlE4.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CngCC8hC.js → index-DtAnPBWP.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-B78xL3s2.js → index-DzG7mkgW.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DIpY0qM5.js → index-H9_X1Cg_.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-C5Sxb1sE.js → index-ITeEHb8L.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-BTPEZTk1.js → index-KtLJXn4s.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-hpvvtAZ3.js → index-RYZgFIwo.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-HhNjnCfe.js → index-gAVxDiTZ.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-DTWg-18U.js → index-paVubXzn.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BqhASEL4.js → index-tUH_6bdJ.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DYAtmqiv.js → index-tVRPgYGr.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-0DnaZGkC.js → index-uSsiwgZ2.js} +1 -1
  131. package/src/assets/web-panel/assets/{initDefaultProps-C3wUb4je.js → initDefaultProps-Ckp7xVZS.js} +1 -1
  132. package/src/assets/web-panel/assets/{motion-D-jYFUNA.js → motion-DUZgCpn6.js} +1 -1
  133. package/src/assets/web-panel/assets/{move-tqb8nwJ2.js → move-B2rttglH.js} +1 -1
  134. package/src/assets/web-panel/assets/{mtc-parser-DSOjMJMz.js → mtc-parser-BYWcLTuN.js} +1 -1
  135. package/src/assets/web-panel/assets/{omit-CJ7VimIW.js → omit-DhHqKeFx.js} +1 -1
  136. package/src/assets/web-panel/assets/{pickAttrs-qXiG1iT3.js → pickAttrs-ANpJaWMO.js} +1 -1
  137. package/src/assets/web-panel/assets/{placementArrow-CkGBcy1Z.js → placementArrow-CfZWe7CA.js} +1 -1
  138. package/src/assets/web-panel/assets/{responsiveObserve-D3WvTlLO.js → responsiveObserve-D7Xz2y-R.js} +1 -1
  139. package/src/assets/web-panel/assets/{slide-BEE2ftge.js → slide-DekqCBY9.js} +1 -1
  140. package/src/assets/web-panel/assets/{statusUtils-CsfBpxiG.js → statusUtils-BET6XU7h.js} +1 -1
  141. package/src/assets/web-panel/assets/{styleChecker-xPrIiJPI.js → styleChecker-qHmJjV62.js} +1 -1
  142. package/src/assets/web-panel/assets/{useFlexGapSupport-C5Yd-SCR.js → useFlexGapSupport-BoMCTNyu.js} +1 -1
  143. package/src/assets/web-panel/assets/{useFs-D_MDS8HI.js → useFs-TdW-NgFC.js} +1 -1
  144. package/src/assets/web-panel/assets/{usePersonalDataHub-BqJh-usA.js → usePersonalDataHub-Dyox7wCu.js} +1 -1
  145. package/src/assets/web-panel/assets/{vnode-chm_p-gz.js → vnode-XUn5S8CP.js} +1 -1
  146. package/src/assets/web-panel/assets/{zoom-3-YDNz0Z.js → zoom-Ls77i8hn.js} +1 -1
  147. package/src/assets/web-panel/index.html +1 -1
  148. package/src/command-manifest.json +8 -1
  149. package/src/commands/a2a.js +19 -4
  150. package/src/commands/activitypub.js +20 -3
  151. package/src/commands/agent.js +27 -5
  152. package/src/commands/audit.js +40 -24
  153. package/src/commands/changelog.js +148 -0
  154. package/src/commands/codeintel.js +68 -0
  155. package/src/commands/collab.js +15 -2
  156. package/src/commands/compliance.js +5 -0
  157. package/src/commands/config.js +4 -1
  158. package/src/commands/dao.js +86 -14
  159. package/src/commands/dev.js +2 -0
  160. package/src/commands/did.js +7 -1
  161. package/src/commands/dlp.js +23 -1
  162. package/src/commands/economy.js +29 -3
  163. package/src/commands/eval.js +7 -0
  164. package/src/commands/evomap.js +26 -0
  165. package/src/commands/governance.js +17 -3
  166. package/src/commands/hardening.js +18 -0
  167. package/src/commands/incentive.js +5 -0
  168. package/src/commands/init.js +46 -2
  169. package/src/commands/kg.js +4 -0
  170. package/src/commands/loop.js +6 -1
  171. package/src/commands/lowcode.js +15 -2
  172. package/src/commands/marketplace.js +40 -6
  173. package/src/commands/matrix.js +20 -1
  174. package/src/commands/memory.js +4 -1
  175. package/src/commands/mtc.js +7 -1
  176. package/src/commands/nostr.js +31 -4
  177. package/src/commands/note.js +7 -4
  178. package/src/commands/plugin.js +125 -5
  179. package/src/commands/pqc.js +5 -0
  180. package/src/commands/reputation.js +10 -1
  181. package/src/commands/scim.js +6 -0
  182. package/src/commands/session.js +32 -10
  183. package/src/commands/siem.js +11 -0
  184. package/src/commands/sla.js +18 -3
  185. package/src/commands/social.js +38 -5
  186. package/src/commands/sso.js +10 -2
  187. package/src/commands/stress.js +23 -4
  188. package/src/commands/team.js +9 -2
  189. package/src/commands/tech.js +2 -0
  190. package/src/commands/tenant.js +10 -1
  191. package/src/commands/terraform.js +6 -0
  192. package/src/commands/update.js +1 -1
  193. package/src/commands/zkp.js +20 -0
  194. package/src/data/changelog.json +189 -0
  195. package/src/gateways/ws/message-dispatcher.js +5 -2
  196. package/src/gateways/ws/remote-session-protocol.js +110 -42
  197. package/src/harness/jsonl-session-store.js +12 -5
  198. package/src/harness/plugin-manager.js +16 -4
  199. package/src/harness/remote-command-ledger.js +46 -15
  200. package/src/harness/worktree-isolator.js +16 -6
  201. package/src/index.js +2 -0
  202. package/src/lib/__tests__/logger.test.js +5 -2
  203. package/src/lib/a2a-protocol.js +25 -1
  204. package/src/lib/activitypub-bridge.js +61 -0
  205. package/src/lib/agent-core.js +2 -0
  206. package/src/lib/agent-economy.js +262 -29
  207. package/src/lib/agent-network.js +7 -1
  208. package/src/lib/agent-team/team-runner.js +25 -9
  209. package/src/lib/agent-team/team-worktree.js +36 -4
  210. package/src/lib/async-hook-supervisor.cjs +102 -16
  211. package/src/lib/audit-logger.js +7 -6
  212. package/src/lib/autonomous-developer.js +60 -0
  213. package/src/lib/changelog.js +252 -0
  214. package/src/lib/chat-core.js +17 -4
  215. package/src/lib/collaboration-governance.js +56 -0
  216. package/src/lib/community-governance.js +68 -0
  217. package/src/lib/compliance-manager.js +63 -0
  218. package/src/lib/cross-chain.js +5 -0
  219. package/src/lib/dao-governance.js +151 -2
  220. package/src/lib/did-manager.js +23 -10
  221. package/src/lib/dlp-engine.js +70 -0
  222. package/src/lib/eval/runner.js +89 -1
  223. package/src/lib/eval/tasks.js +170 -0
  224. package/src/lib/eval/trend.js +16 -1
  225. package/src/lib/evolution-system.js +92 -0
  226. package/src/lib/evomap-federation.js +55 -0
  227. package/src/lib/evomap-governance.js +94 -0
  228. package/src/lib/fatal-handler.js +17 -1
  229. package/src/lib/hardening-manager.js +73 -0
  230. package/src/lib/hierarchical-memory.js +14 -8
  231. package/src/lib/knowledge-exporter.js +8 -2
  232. package/src/lib/knowledge-graph.js +79 -0
  233. package/src/lib/llm-providers.js +23 -14
  234. package/src/lib/logger.js +4 -1
  235. package/src/lib/lsp/__tests__/benchmark.test.js +88 -0
  236. package/src/lib/lsp/__tests__/lsp-client.test.js +11 -0
  237. package/src/lib/lsp/__tests__/lsp-manager.test.js +69 -0
  238. package/src/lib/lsp/benchmark.js +257 -0
  239. package/src/lib/lsp/lsp-client.js +30 -9
  240. package/src/lib/lsp/lsp-manager.js +54 -2
  241. package/src/lib/lsp/lsp-server-registry.js +15 -4
  242. package/src/lib/matrix-bridge.js +84 -0
  243. package/src/lib/memory-manager.js +5 -3
  244. package/src/lib/nostr-bridge.js +53 -0
  245. package/src/lib/permission-engine.js +22 -4
  246. package/src/lib/plugin-runtime/__tests__/remote-source.test.js +256 -0
  247. package/src/lib/plugin-runtime/hooks.js +20 -4
  248. package/src/lib/plugin-runtime/install.js +9 -1
  249. package/src/lib/plugin-runtime/monitors.js +20 -4
  250. package/src/lib/plugin-runtime/policy.js +9 -1
  251. package/src/lib/plugin-runtime/remote-source.js +240 -0
  252. package/src/lib/plugin-runtime/signature.js +16 -0
  253. package/src/lib/pqc-manager.js +64 -0
  254. package/src/lib/reputation-optimizer.js +101 -0
  255. package/src/lib/sandbox-egress-proxy.js +195 -59
  256. package/src/lib/sandbox-fs-policy.js +112 -0
  257. package/src/lib/sandbox-network-policy.js +44 -5
  258. package/src/lib/sandbox-v2.js +14 -14
  259. package/src/lib/scim-manager.js +36 -0
  260. package/src/lib/session-manager.js +5 -2
  261. package/src/lib/settings-hooks.cjs +1 -0
  262. package/src/lib/siem-exporter.js +45 -0
  263. package/src/lib/skill-loader.js +20 -2
  264. package/src/lib/skill-marketplace.js +83 -0
  265. package/src/lib/sla-manager.js +88 -0
  266. package/src/lib/social-manager.js +74 -0
  267. package/src/lib/stress-tester.js +65 -0
  268. package/src/lib/tech-learning-engine.js +75 -0
  269. package/src/lib/telemetry/span-recorder.js +12 -1
  270. package/src/lib/tenant-saas.js +107 -0
  271. package/src/lib/terraform-manager.js +67 -0
  272. package/src/lib/token-incentive.js +180 -29
  273. package/src/lib/wallet-manager.js +81 -35
  274. package/src/lib/zkp-engine.js +87 -0
  275. package/src/repl/agent-repl.js +17 -2
  276. package/src/runtime/__tests__/auto-pin.test.js +104 -0
  277. package/src/runtime/agent-core.js +241 -68
  278. package/src/runtime/auto-pin.js +117 -0
  279. package/src/runtime/headless-runner.js +35 -0
  280. package/src/assets/web-panel/assets/OrderTableRenderer-CRIFE2Tj.js +0 -1
  281. package/src/assets/web-panel/assets/Projects-CGcNIs_g.js +0 -1
  282. package/src/assets/web-panel/assets/Terminal-ZzU0Io1Y.js +0 -3
  283. package/src/assets/web-panel/assets/devWarning-DxwmsL4j.js +0 -1
  284. package/src/assets/web-panel/assets/index-Cg2ldRfU.js +0 -1
  285. package/src/assets/web-panel/assets/index-Dwzo-dtJ.js +0 -1
@@ -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,62 @@ 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
+ // A direct-WS client puts the idempotency key at the message top level, but
43
+ // the RELAY path (`_handleRemoteEncryptedControl`) decrypts the whole mobile
44
+ // control payload into `message.event`, so a relay-paired mobile's commandId
45
+ // lands at `event.commandId`. Read either — otherwise the primary takeover
46
+ // path (relay-paired mobile) never consults the ledger and a reconnect
47
+ // re-runs the agent turn, defeating the entire Phase 5 guarantee.
48
+ const commandId = message.commandId ?? message.event?.commandId;
49
+ const seq = message.seq ?? message.event?.seq;
50
+ if (!commandId) return forward();
51
+ // Create the ledger SYNCHRONOUSLY (no await between the check and the assign)
52
+ // so two concurrent re-deliveries of the same commandId share ONE ledger and
53
+ // coalesce — a lazy `await import()` here would let each build its own ledger
54
+ // and both would execute, defeating the whole guarantee.
55
+ if (!server._remoteControlLedger) {
56
+ server._remoteControlLedger = new RemoteCommandLedger();
57
+ }
58
+ const outcome = await server._remoteControlLedger.apply(
59
+ { commandId, deviceId: clientId, seq },
60
+ async () => {
61
+ await forward();
62
+ return true;
63
+ },
64
+ );
65
+ if (outcome.status === "replayed") {
66
+ reply(server, ws, message.id, "remote-session-published", {
67
+ delivered: 0,
68
+ replayed: true,
69
+ commandId,
70
+ applyIndex: outcome.applyIndex,
71
+ });
72
+ } else if (outcome.status === "rejected") {
73
+ reply(server, ws, message.id, "error", {
74
+ code: "COMMAND_REJECTED",
75
+ commandId,
76
+ message: outcome.reason,
77
+ });
78
+ }
79
+ return outcome;
80
+ }
81
+
25
82
  function attachPairingUri(server, result) {
26
83
  const relayUrl = server.remoteSessionRelayUrl;
27
84
  const hostPeerId = server.remoteSessionPeerId;
@@ -395,49 +452,60 @@ export async function handleRemoteSessionPublish(
395
452
  id: message.id,
396
453
  sessionId: session.agentSessionId,
397
454
  };
398
- if (message.event.type === "prompt") {
399
- if (
400
- typeof message.event.content !== "string" ||
401
- !message.event.content.trim()
402
- ) {
403
- throw new Error("prompt content is required");
404
- }
405
- // Record the shape, not the content — the audit trail must stay useful
406
- // without hoarding potentially sensitive session prompts.
407
- audit(server, {
408
- sessionId: message.remoteSessionId,
409
- actor: clientId,
410
- action: "control.prompt",
411
- detail: { chars: message.event.content.length },
412
- });
413
- handleSessionMessage(server, message.id, ws, {
414
- ...controlMessage,
415
- content: message.event.content,
416
- });
417
- } else if (message.event.type === "approval.resolve") {
418
- audit(server, {
419
- sessionId: message.remoteSessionId,
420
- actor: clientId,
421
- action: "control.approval",
422
- detail: {
423
- requestId: message.event.requestId || message.event.approvalId,
424
- approved: message.event.answer ?? message.event.approved,
425
- },
426
- });
427
- await handleSessionAnswer(server, message.id, ws, {
428
- ...controlMessage,
429
- requestId: message.event.requestId || message.event.approvalId,
430
- answer: message.event.answer ?? message.event.approved,
431
- });
432
- } else if (message.event.type === "interrupt") {
433
- audit(server, {
434
- sessionId: message.remoteSessionId,
435
- actor: clientId,
436
- action: "control.interrupt",
437
- detail: null,
438
- });
439
- await handleSessionInterrupt(server, message.id, ws, controlMessage);
455
+ // Validate up-front so a malformed control event errors identically
456
+ // whether or not it carries a commandId — idempotency must never change
457
+ // validation semantics (a bad prompt must not consume a commandId slot).
458
+ if (
459
+ message.event.type === "prompt" &&
460
+ (typeof message.event.content !== "string" ||
461
+ !message.event.content.trim())
462
+ ) {
463
+ throw new Error("prompt content is required");
440
464
  }
465
+ // Idempotent forward: a control event with a stable commandId runs its
466
+ // side effect (audit + dispatch into the host agent) AT MOST ONCE, so a
467
+ // reconnecting device re-sending the same prompt/approval/interrupt gets a
468
+ // `replayed` ack instead of a second agent turn. No commandId → forwarded
469
+ // directly, byte-identical to before.
470
+ await applyControlIdempotent(server, clientId, ws, message, async () => {
471
+ if (message.event.type === "prompt") {
472
+ // Record the shape, not the content — the audit trail must stay
473
+ // useful without hoarding potentially sensitive session prompts.
474
+ audit(server, {
475
+ sessionId: message.remoteSessionId,
476
+ actor: clientId,
477
+ action: "control.prompt",
478
+ detail: { chars: message.event.content.length },
479
+ });
480
+ handleSessionMessage(server, message.id, ws, {
481
+ ...controlMessage,
482
+ content: message.event.content,
483
+ });
484
+ } else if (message.event.type === "approval.resolve") {
485
+ audit(server, {
486
+ sessionId: message.remoteSessionId,
487
+ actor: clientId,
488
+ action: "control.approval",
489
+ detail: {
490
+ requestId: message.event.requestId || message.event.approvalId,
491
+ approved: message.event.answer ?? message.event.approved,
492
+ },
493
+ });
494
+ await handleSessionAnswer(server, message.id, ws, {
495
+ ...controlMessage,
496
+ requestId: message.event.requestId || message.event.approvalId,
497
+ answer: message.event.answer ?? message.event.approved,
498
+ });
499
+ } else if (message.event.type === "interrupt") {
500
+ audit(server, {
501
+ sessionId: message.remoteSessionId,
502
+ actor: clientId,
503
+ action: "control.interrupt",
504
+ detail: null,
505
+ });
506
+ await handleSessionInterrupt(server, message.id, ws, controlMessage);
507
+ }
508
+ });
441
509
  return;
442
510
  }
443
511
 
@@ -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 });
@@ -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
  }
package/src/index.js CHANGED
@@ -7,6 +7,7 @@ import { registerStatusCommand } from "./commands/status.js";
7
7
  import { registerServicesCommand } from "./commands/services.js";
8
8
  import { registerConfigCommand } from "./commands/config.js";
9
9
  import { registerUpdateCommand } from "./commands/update.js";
10
+ import { registerChangelogCommand } from "./commands/changelog.js";
10
11
  import { registerDoctorCommand } from "./commands/doctor.js";
11
12
  import { registerPairCommand } from "./commands/pair.js";
12
13
  import { registerNotificationCommand } from "./commands/notification.js";
@@ -418,6 +419,7 @@ export function createProgram(opts = {}) {
418
419
  registerServicesCommand(program);
419
420
  registerConfigCommand(program);
420
421
  registerUpdateCommand(program);
422
+ registerChangelogCommand(program);
421
423
  registerDoctorCommand(program);
422
424
  registerPairCommand(program);
423
425
  registerNotificationCommand(program);
@@ -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";