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
@@ -64,6 +64,7 @@ import {
64
64
  PromptCompressor,
65
65
  getContextWindow,
66
66
  } from "../harness/prompt-compressor.js";
67
+ import { buildAutoPinPredicate } from "../runtime/auto-pin.js";
67
68
  import { feature } from "../lib/feature-flags.js";
68
69
  import { recordCompressionMetric } from "../lib/compression-telemetry.js";
69
70
  import {
@@ -121,6 +122,20 @@ let _permissionConfirm = null;
121
122
  let _managedPermissionRulesOnly = false;
122
123
  // .claude/settings.json `hooks` block (decision-capable PreToolUse/PostToolUse).
123
124
  let _settingsHooks = null;
125
+ // Installed-plugin background monitors (Phase 3.3i) — a supervisor owning any
126
+ // long-running/interval watcher processes a trusted plugin declared; reaped in
127
+ // the SessionEnd cleanup so nothing outlives the REPL.
128
+ let _pluginMonitors = null;
129
+ // Installed-plugin `bin` PATH injection (Phase 3.3n) — restore() puts PATH back
130
+ // at SessionEnd so plugin executables are only resolvable during the session.
131
+ let _pluginBinRestore = null;
132
+ // Installed-plugin `settings` default env (Phase 3.3o) — restore() removes the
133
+ // plugin-provided env-var defaults at SessionEnd (session-scoped).
134
+ let _pluginSettingsRestore = null;
135
+ // Async settings-hook supervisor (Phase 6) — owns fire-and-forget `async:true`
136
+ // hook processes; their results/rewakes drain into the next turn's context.
137
+ // Lazily created when the first async hook is dispatched; reaped at SessionEnd.
138
+ let _asyncHookSupervisor = null;
124
139
  // .claude/settings.json `respondToBashCommands` (Claude-Code 2.1.186): whether a
125
140
  // `!command` auto-triggers an assistant response to its output. undefined =
126
141
  // unset → defaults OFF (opt-in) in shouldRespondToBashCommands.
@@ -402,10 +417,15 @@ export async function startAgentRepl(options = {}) {
402
417
  // Unset → agent-core's 180s default (matches cc chat/ask). Set to 0 to
403
418
  // disable. Left undefined here means "use the default".
404
419
  let _streamStallTimeoutMs;
420
+ // Auto-pin (OPT-IN, off by default): when set, compaction pins the original
421
+ // task. Resolved from config `context.autoPin` or CC_AUTO_PIN=1; falsy → the
422
+ // compress calls below pass no pin predicate (byte-identical default).
423
+ let _autoPinOpt;
405
424
  try {
406
425
  const { loadConfig } = await import("../lib/config-manager.js");
407
426
  const _cfg = loadConfig();
408
427
  _visionModel = _cfg?.llm?.visionModel || undefined;
428
+ _autoPinOpt = _cfg?.context?.autoPin;
409
429
  const raw = _cfg?.llm?.streamStallTimeoutMs;
410
430
  const t = Number(raw);
411
431
  // Accept 0 (explicit disable) — only ignore absent/invalid values.
@@ -436,10 +456,12 @@ export async function startAgentRepl(options = {}) {
436
456
  const _fallbackChatFn = _fallbackModels.length
437
457
  ? makeFallbackChatFn({
438
458
  fallbackModels: _fallbackModels,
439
- onFallback: ({ from, to, error }) =>
459
+ onFallback: ({ from, to, error, skipped, reason, crossProvider }) =>
440
460
  logger.info(
441
461
  chalk.yellow(
442
- `[fallback] model "${from}" failed (${error}); retrying with "${to}"`,
462
+ skipped
463
+ ? `[fallback] "${to}" skipped (${reason})`
464
+ : `[fallback] model "${from}" failed (${error}); retrying with ${crossProvider ? "cross-provider " : ""}"${to}"`,
443
465
  ),
444
466
  ),
445
467
  })
@@ -461,6 +483,15 @@ export async function startAgentRepl(options = {}) {
461
483
  if (feature("PROMPT_COMPRESSOR")) {
462
484
  _compressor = new PromptCompressor({ model, provider });
463
485
  }
486
+ if (process.env.CC_AUTO_PIN === "1") _autoPinOpt = _autoPinOpt || true;
487
+ // Compaction options shared by /compact + auto-compact. Adds the opt-in
488
+ // pin predicate only when auto-pin is enabled; otherwise byte-identical.
489
+ const _compactOpts = (msgs) => {
490
+ const base = { preserveToolPairs: true };
491
+ if (!_autoPinOpt) return base;
492
+ const isPinned = buildAutoPinPredicate(msgs, _autoPinOpt);
493
+ return isPinned ? { ...base, isPinned } : base;
494
+ };
464
495
 
465
496
  // Initialize permanent memory
466
497
  let permanentMemory = null;
@@ -610,9 +641,14 @@ export async function startAgentRepl(options = {}) {
610
641
  const { loadHooks, projectHookTrustNotice } =
611
642
  await import("../lib/settings-hooks.cjs");
612
643
  const loaded = loadHooks({ cwd: process.cwd() });
644
+ // Fold in installed plugins' hooks/hooks.json (Phase 3.3c).
645
+ const { mergePluginHooks } = await import("../lib/plugin-runtime/hooks.js");
646
+ const effectiveHooks = mergePluginHooks(loaded.hooks, {
647
+ cwd: process.cwd(),
648
+ });
613
649
  _settingsHooks =
614
- loaded.hooks && Object.keys(loaded.hooks).length > 0
615
- ? loaded.hooks
650
+ effectiveHooks && Object.keys(effectiveHooks).length > 0
651
+ ? effectiveHooks
616
652
  : null;
617
653
  // First-run trust notice for an untrusted/cloned repo's shell-running
618
654
  // hooks (Claude-Code 2.1.195 parity). Best-effort, stderr-only.
@@ -626,6 +662,60 @@ export async function startAgentRepl(options = {}) {
626
662
  _settingsHooks = null;
627
663
  }
628
664
 
665
+ // Start installed plugins' background monitors (Phase 3.3i). Trust-gated
666
+ // inside collectPluginMonitors — only user/local-scope and explicitly-trusted
667
+ // project plugins get a process spawned. Reaped in the SessionEnd cleanup +
668
+ // a process-exit backstop, so no monitor outlives the session.
669
+ try {
670
+ const { collectPluginMonitors } =
671
+ await import("../lib/plugin-runtime/monitors.js");
672
+ const monitors = collectPluginMonitors({ cwd: process.cwd() });
673
+ if (monitors.length > 0) {
674
+ const { PluginMonitorSupervisor } =
675
+ await import("../lib/plugin-monitor-supervisor.js");
676
+ _pluginMonitors = new PluginMonitorSupervisor();
677
+ const started = _pluginMonitors.start(monitors);
678
+ if (started.length > 0) {
679
+ process.stderr.write(
680
+ ` monitors: started ${started.length} from trusted plugin(s): ${started.join(", ")}\n`,
681
+ );
682
+ }
683
+ }
684
+ } catch (_err) {
685
+ _pluginMonitors = null;
686
+ }
687
+
688
+ // Put trusted plugins' bin/ executables on PATH for the session (Phase 3.3n),
689
+ // restored at SessionEnd. Trust-gated inside collectPluginBinDirs.
690
+ try {
691
+ const { applyPluginBinPath } = await import("../lib/plugin-runtime/bin.js");
692
+ const res = applyPluginBinPath({ cwd: process.cwd() });
693
+ _pluginBinRestore = res.restore;
694
+ if (res.added.length > 0) {
695
+ process.stderr.write(
696
+ ` bin: added ${res.added.length} plugin bin dir(s) to PATH\n`,
697
+ );
698
+ }
699
+ } catch (_err) {
700
+ _pluginBinRestore = null;
701
+ }
702
+
703
+ // Apply trusted plugins' default env vars (Phase 3.3o) — only for env keys the
704
+ // user/system didn't already set; restored at SessionEnd.
705
+ try {
706
+ const { applyPluginSettingsEnv } =
707
+ await import("../lib/plugin-runtime/settings.js");
708
+ const res = applyPluginSettingsEnv({ cwd: process.cwd() });
709
+ _pluginSettingsRestore = res.restore;
710
+ if (res.added.length > 0) {
711
+ process.stderr.write(
712
+ ` settings: applied ${res.added.length} plugin env default(s)\n`,
713
+ );
714
+ }
715
+ } catch (_err) {
716
+ _pluginSettingsRestore = null;
717
+ }
718
+
629
719
  // Resume existing session or create new one
630
720
  const useJsonl = feature("JSONL_SESSION");
631
721
 
@@ -980,6 +1070,27 @@ export async function startAgentRepl(options = {}) {
980
1070
  } catch (_err) {
981
1071
  // Non-critical
982
1072
  }
1073
+ // settings.json SessionResume hooks: a persisted transcript was just
1074
+ // replayed into this interactive session (distinct from SessionStart).
1075
+ // Observe-only, best-effort — never blocks entering the REPL.
1076
+ if (_settingsHooks && messages.some((m) => m.role !== "system")) {
1077
+ try {
1078
+ const { runObserveHooks } =
1079
+ await import("../lib/settings-hook-events.cjs");
1080
+ runObserveHooks(
1081
+ _settingsHooks,
1082
+ "SessionResume",
1083
+ {
1084
+ session_id: sessionId,
1085
+ resumed_from: sessionId,
1086
+ cwd: process.cwd(),
1087
+ },
1088
+ { cwd: process.cwd() },
1089
+ );
1090
+ } catch {
1091
+ /* observe-only */
1092
+ }
1093
+ }
983
1094
  // Resume recap (offline, extractive — no LLM): a quick "where were we"
984
1095
  // so the user doesn't have to scroll the old transcript.
985
1096
  try {
@@ -1091,6 +1202,7 @@ export async function startAgentRepl(options = {}) {
1091
1202
  "/quit",
1092
1203
  "/reindex",
1093
1204
  "/release-notes",
1205
+ "/reload-plugins",
1094
1206
  "/reload-skills",
1095
1207
  "/review",
1096
1208
  "/rewind",
@@ -1217,6 +1329,25 @@ export async function startAgentRepl(options = {}) {
1217
1329
  /* already aborted */
1218
1330
  }
1219
1331
  _turnAbort = null;
1332
+ // settings.json SessionPause hooks: the user interrupted the in-flight
1333
+ // turn — the session stays open, the current work is suspended. The
1334
+ // keypress handler can't await, so fire observe-only fire-and-forget.
1335
+ if (_settingsHooks) {
1336
+ import("../lib/settings-hook-events.cjs")
1337
+ .then(({ runObserveHooks }) =>
1338
+ runObserveHooks(
1339
+ _settingsHooks,
1340
+ "SessionPause",
1341
+ {
1342
+ session_id: sessionId,
1343
+ reason: "user-interrupt",
1344
+ cwd: process.cwd(),
1345
+ },
1346
+ { cwd: process.cwd() },
1347
+ ),
1348
+ )
1349
+ .catch(() => {});
1350
+ }
1220
1351
  return;
1221
1352
  }
1222
1353
 
@@ -1604,6 +1735,9 @@ export async function startAgentRepl(options = {}) {
1604
1735
  logger.log(
1605
1736
  ` ${chalk.cyan("/reload-skills")} Re-scan skill layers without restarting`,
1606
1737
  );
1738
+ logger.log(
1739
+ ` ${chalk.cyan("/reload-plugins")} Re-scan installed plugins after add/trust/upgrade`,
1740
+ );
1607
1741
  logger.log(
1608
1742
  ` ${chalk.cyan("/review")} Diff-first code review (/review [high] [--security|--simplify] [--fix])`,
1609
1743
  );
@@ -2414,7 +2548,7 @@ export async function startAgentRepl(options = {}) {
2414
2548
  if (_compressor && messages.length > 3) {
2415
2549
  const { messages: compacted, stats } = await _compressor.compress(
2416
2550
  messages,
2417
- { preserveToolPairs: true },
2551
+ _compactOpts(messages),
2418
2552
  );
2419
2553
  messages.length = 0;
2420
2554
  messages.push(...compacted);
@@ -2564,6 +2698,117 @@ export async function startAgentRepl(options = {}) {
2564
2698
  return;
2565
2699
  }
2566
2700
 
2701
+ // `/reload-plugins` (Phase 3.3m): re-scan installed plugins after an
2702
+ // install / trust / upgrade WITHOUT restarting — resets memoized LSP
2703
+ // registration + managed-policy/trust caches, re-merges the effective hook
2704
+ // map, and restarts the monitor supervisor with the fresh set. Already-
2705
+ // connected MCP servers stay for this session (new ones load next session).
2706
+ if (trimmed === "/reload-plugins") {
2707
+ try {
2708
+ const cwd = process.cwd();
2709
+ const { reloadPluginRuntime } =
2710
+ await import("../lib/plugin-runtime/reload.js");
2711
+ const sum = reloadPluginRuntime({ cwd });
2712
+
2713
+ // Re-merge plugin hooks onto the user's settings hooks (live session).
2714
+ try {
2715
+ const { loadHooks } = await import("../lib/settings-hooks.cjs");
2716
+ const { mergePluginHooks } =
2717
+ await import("../lib/plugin-runtime/hooks.js");
2718
+ const base = loadHooks({ cwd }).hooks;
2719
+ const merged = mergePluginHooks(base, { cwd });
2720
+ _settingsHooks =
2721
+ merged && Object.keys(merged).length > 0 ? merged : null;
2722
+ } catch {
2723
+ /* hooks re-merge is best-effort */
2724
+ }
2725
+
2726
+ // settings.json ConfigChange hooks (Claude-Code parity): the live
2727
+ // hooks / permissions / trusted-plugin set just changed, so fire
2728
+ // ConfigChange with the FRESH hook set — a policy hook can observe or
2729
+ // react (e.g. re-audit the newly-trusted config). Best-effort.
2730
+ if (_settingsHooks) {
2731
+ try {
2732
+ const { runObserveHooks, dispatchAsyncHooks } =
2733
+ await import("../lib/settings-hook-events.cjs");
2734
+ const payload = {
2735
+ session_id: sessionId || null,
2736
+ source: "reload-plugins",
2737
+ };
2738
+ runObserveHooks(_settingsHooks, "ConfigChange", payload, { cwd });
2739
+ if (!_asyncHookSupervisor) {
2740
+ const { AsyncHookSupervisor } =
2741
+ await import("../lib/async-hook-supervisor.cjs");
2742
+ _asyncHookSupervisor = new AsyncHookSupervisor();
2743
+ }
2744
+ dispatchAsyncHooks(_settingsHooks, "ConfigChange", payload, {
2745
+ cwd,
2746
+ supervisor: _asyncHookSupervisor,
2747
+ });
2748
+ } catch {
2749
+ /* ConfigChange hooks are best-effort */
2750
+ }
2751
+ }
2752
+
2753
+ // Restart background monitors with the fresh, trust-gated set.
2754
+ try {
2755
+ const { collectPluginMonitors } =
2756
+ await import("../lib/plugin-runtime/monitors.js");
2757
+ if (_pluginMonitors) {
2758
+ _pluginMonitors.stopAll();
2759
+ _pluginMonitors = null;
2760
+ }
2761
+ const monitors = collectPluginMonitors({ cwd });
2762
+ if (monitors.length > 0) {
2763
+ const { PluginMonitorSupervisor } =
2764
+ await import("../lib/plugin-monitor-supervisor.js");
2765
+ _pluginMonitors = new PluginMonitorSupervisor();
2766
+ _pluginMonitors.start(monitors);
2767
+ }
2768
+ } catch {
2769
+ /* monitor restart is best-effort */
2770
+ }
2771
+
2772
+ // Re-apply plugin bin PATH (a newly-trusted plugin's executables).
2773
+ try {
2774
+ const { applyPluginBinPath } =
2775
+ await import("../lib/plugin-runtime/bin.js");
2776
+ if (_pluginBinRestore) _pluginBinRestore();
2777
+ const res = applyPluginBinPath({ cwd });
2778
+ _pluginBinRestore = res.restore;
2779
+ } catch {
2780
+ /* bin re-apply is best-effort */
2781
+ }
2782
+
2783
+ // Re-apply plugin default env vars (a newly-trusted plugin's settings).
2784
+ try {
2785
+ const { applyPluginSettingsEnv } =
2786
+ await import("../lib/plugin-runtime/settings.js");
2787
+ if (_pluginSettingsRestore) _pluginSettingsRestore();
2788
+ const res = applyPluginSettingsEnv({ cwd });
2789
+ _pluginSettingsRestore = res.restore;
2790
+ } catch {
2791
+ /* settings re-apply is best-effort */
2792
+ }
2793
+
2794
+ logger.log(
2795
+ chalk.green(
2796
+ `✔ plugins reloaded — ${sum.plugins} plugin(s): ` +
2797
+ `${sum.skills} skill layer(s), ${sum.agents} agent dir(s), ` +
2798
+ `${sum.lspRegistered} LSP server(s), ${sum.hooks} hook event(s), ` +
2799
+ `${sum.mcp} MCP server(s), ${sum.monitors} monitor(s)`,
2800
+ ),
2801
+ );
2802
+ logger.log(
2803
+ chalk.gray(" (newly-added MCP servers connect on the next session)"),
2804
+ );
2805
+ } catch (err) {
2806
+ logger.error(`/reload-plugins failed: ${err.message}`);
2807
+ }
2808
+ prompt();
2809
+ return;
2810
+ }
2811
+
2567
2812
  // `/review` — diff-first code review of your changes (Claude-Code
2568
2813
  // /code-review parity). Reuses the `cc review` machinery: collects the git
2569
2814
  // diff and runs ONE focused agent turn. Read-only by default; `--fix`
@@ -3743,11 +3988,95 @@ export async function startAgentRepl(options = {}) {
3743
3988
  if (ups.additionalContext) {
3744
3989
  userContent += `\n\n[hook context]\n${ups.additionalContext}`;
3745
3990
  }
3991
+ // Fire-and-forget the `async:true` UserPromptSubmit hooks (Phase 6): a
3992
+ // long-running check (background tests, CI status) runs ALONGSIDE this
3993
+ // turn without blocking it; its result/rewake surfaces on a later turn
3994
+ // via the async-hook drain below. Lazily create the supervisor.
3995
+ const { dispatchAsyncHooks } =
3996
+ await import("../lib/settings-hook-events.cjs");
3997
+ if (!_asyncHookSupervisor) {
3998
+ const { AsyncHookSupervisor } =
3999
+ await import("../lib/async-hook-supervisor.cjs");
4000
+ _asyncHookSupervisor = new AsyncHookSupervisor();
4001
+ }
4002
+ dispatchAsyncHooks(
4003
+ _settingsHooks,
4004
+ "UserPromptSubmit",
4005
+ { prompt: userContent },
4006
+ { cwd: process.cwd(), supervisor: _asyncHookSupervisor },
4007
+ );
3746
4008
  } catch (_err) {
3747
4009
  // settings hook dispatch is best-effort
3748
4010
  }
3749
4011
  }
3750
4012
 
4013
+ // Plugin background-monitor output (Phase 3.3i/Phase 6): surface anything a
4014
+ // trusted plugin's monitor captured SINCE the last turn as additionalContext,
4015
+ // so the agent sees e.g. a background test failure or a tailed log on its
4016
+ // next turn. Drained (cleared) so each line is shown once; bounded so a noisy
4017
+ // monitor can't blow up the prompt.
4018
+ if (_pluginMonitors) {
4019
+ try {
4020
+ const recs = _pluginMonitors.drainOutputs();
4021
+ if (recs.length > 0) {
4022
+ const shown = recs.slice(-40);
4023
+ const lines = shown
4024
+ .map((r) => ` [${r.monitor}/${r.stream}] ${r.line}`)
4025
+ .join("\n");
4026
+ const omitted =
4027
+ recs.length > shown.length
4028
+ ? `\n … (${recs.length - shown.length} earlier line(s) omitted)`
4029
+ : "";
4030
+ userContent += `\n\n[plugin monitors — new output since last turn]\n${lines}${omitted}`;
4031
+ }
4032
+ } catch (_err) {
4033
+ // monitor drain is best-effort — never blocks a turn
4034
+ }
4035
+ }
4036
+
4037
+ // Async settings-hook output (Phase 6): fold in any `async:true` hook that
4038
+ // FINISHED since the last turn. Failed `asyncRewake` hooks are surfaced
4039
+ // first + prominently (the "rewake" — a background test failure re-engages
4040
+ // the agent with the structured error) followed by the plain results.
4041
+ // Drained (cleared) so each is shown once.
4042
+ if (_asyncHookSupervisor) {
4043
+ try {
4044
+ const rewakes = _asyncHookSupervisor.drainRewakes();
4045
+ const results = _asyncHookSupervisor.drainResults();
4046
+ if (rewakes.length > 0) {
4047
+ const lines = rewakes
4048
+ .map(
4049
+ (r) =>
4050
+ ` ✗ ${r.command}${r.event ? ` (${r.event})` : ""}: ${
4051
+ r.error || "failed"
4052
+ }`,
4053
+ )
4054
+ .join("\n");
4055
+ userContent += `\n\n[async hook — REWAKE: a background hook failed, address it]\n${lines}`;
4056
+ }
4057
+ // Non-rewake informational results (successful context / non-opted
4058
+ // failures). Rewake records already shown above are excluded to avoid
4059
+ // duplication.
4060
+ const info = results.filter((r) => !(r.asyncRewake === true && !r.ok));
4061
+ const ctxLines = info
4062
+ .map((r) => {
4063
+ if (r.skipped) return ` … ${r.command}: ${r.error}`;
4064
+ if (r.ok && r.additionalContext)
4065
+ return ` ✔ ${r.command}: ${r.additionalContext}`;
4066
+ if (!r.ok) return ` ✗ ${r.command}: ${r.error || "failed"}`;
4067
+ return null;
4068
+ })
4069
+ .filter(Boolean);
4070
+ if (ctxLines.length > 0) {
4071
+ userContent += `\n\n[async hooks — finished since last turn]\n${ctxLines
4072
+ .slice(-20)
4073
+ .join("\n")}`;
4074
+ }
4075
+ } catch (_err) {
4076
+ // async-hook drain is best-effort — never blocks a turn
4077
+ }
4078
+ }
4079
+
3751
4080
  // IDE live context (Claude-Code parity): re-shared on every prompt while
3752
4081
  // an IDE bridge is connected — the user's selection moves between turns.
3753
4082
  // Ephemeral: persistence stores effectivePrompt, not this snapshot.
@@ -3933,6 +4262,14 @@ export async function startAgentRepl(options = {}) {
3933
4262
  // merge fires exactly once (2.1.187 parity; see _sanitizeRolesNextTurn).
3934
4263
  const _mergeRolesThisTurn = _sanitizeRolesNextTurn;
3935
4264
  _sanitizeRolesNextTurn = false;
4265
+ // Ensure the async-hook supervisor exists so `async:true` PostToolUse
4266
+ // hooks (fired inside the loop, per tool call) can be dispatched
4267
+ // fire-and-forget; their results/rewakes drain into the next turn above.
4268
+ if (_settingsHooks && !_asyncHookSupervisor) {
4269
+ const { AsyncHookSupervisor } =
4270
+ await import("../lib/async-hook-supervisor.cjs");
4271
+ _asyncHookSupervisor = new AsyncHookSupervisor();
4272
+ }
3936
4273
  const {
3937
4274
  content: response,
3938
4275
  usageEvents,
@@ -3996,6 +4333,7 @@ export async function startAgentRepl(options = {}) {
3996
4333
  permissionRules: _permissionRules,
3997
4334
  permissionConfirm: _permissionConfirm,
3998
4335
  settingsHooks: _settingsHooks,
4336
+ hookSupervisor: _asyncHookSupervisor,
3999
4337
  classifyAllShell: _classifyAllShell,
4000
4338
  // Interactive session: gate run_code through the ApprovalGate (like
4001
4339
  // run_shell) so a strict tier prompts before arbitrary code runs.
@@ -4137,7 +4475,7 @@ export async function startAgentRepl(options = {}) {
4137
4475
  try {
4138
4476
  const { messages: compacted, stats } = await _compressor.compress(
4139
4477
  messages,
4140
- { preserveToolPairs: true },
4478
+ _compactOpts(messages),
4141
4479
  );
4142
4480
  messages.length = 0;
4143
4481
  messages.push(...compacted);
@@ -4171,6 +4509,37 @@ export async function startAgentRepl(options = {}) {
4171
4509
  // Non-critical
4172
4510
  }
4173
4511
  }
4512
+
4513
+ // settings.json Stop hooks (Claude-Code parity): the agent just finished a
4514
+ // turn. Sync Stop hooks observe; `async:true` Stop hooks fire-and-forget
4515
+ // (the canonical "run the test suite after the turn" trigger) with their
4516
+ // results/rewakes drained into the NEXT turn's context (see the async-hook
4517
+ // drain above). Best-effort — never break turn completion.
4518
+ if (_settingsHooks) {
4519
+ try {
4520
+ const { runObserveHooks, dispatchAsyncHooks } =
4521
+ await import("../lib/settings-hook-events.cjs");
4522
+ runObserveHooks(
4523
+ _settingsHooks,
4524
+ "Stop",
4525
+ { session_id: sessionId || null },
4526
+ { cwd: process.cwd() },
4527
+ );
4528
+ if (!_asyncHookSupervisor) {
4529
+ const { AsyncHookSupervisor } =
4530
+ await import("../lib/async-hook-supervisor.cjs");
4531
+ _asyncHookSupervisor = new AsyncHookSupervisor();
4532
+ }
4533
+ dispatchAsyncHooks(
4534
+ _settingsHooks,
4535
+ "Stop",
4536
+ {},
4537
+ { cwd: process.cwd(), supervisor: _asyncHookSupervisor },
4538
+ );
4539
+ } catch (_e) {
4540
+ // Stop-hook dispatch is best-effort
4541
+ }
4542
+ }
4174
4543
  } catch (err) {
4175
4544
  _turnAbort = null;
4176
4545
  // Esc interrupt: an aborted turn is normal flow, not an error — the
@@ -4331,6 +4700,48 @@ export async function startAgentRepl(options = {}) {
4331
4700
  // Non-critical
4332
4701
  }
4333
4702
 
4703
+ // Reap plugin background monitors (Phase 3.3i) — clear interval timers and
4704
+ // SIGTERM every watcher child so no monitor process outlives the session.
4705
+ if (_pluginMonitors) {
4706
+ try {
4707
+ _pluginMonitors.stopAll();
4708
+ } catch (_e) {
4709
+ // Non-critical
4710
+ }
4711
+ _pluginMonitors = null;
4712
+ }
4713
+
4714
+ // Reap async settings-hook processes (Phase 6) — SIGTERM any fire-and-forget
4715
+ // `async:true` hook still running so none outlives the session.
4716
+ if (_asyncHookSupervisor) {
4717
+ try {
4718
+ _asyncHookSupervisor.stopAll();
4719
+ } catch (_e) {
4720
+ // Non-critical
4721
+ }
4722
+ _asyncHookSupervisor = null;
4723
+ }
4724
+
4725
+ // Restore PATH — drop the plugin bin dirs added at startup (Phase 3.3n).
4726
+ if (_pluginBinRestore) {
4727
+ try {
4728
+ _pluginBinRestore();
4729
+ } catch (_e) {
4730
+ // Non-critical
4731
+ }
4732
+ _pluginBinRestore = null;
4733
+ }
4734
+
4735
+ // Drop plugin-provided default env vars added at startup (Phase 3.3o).
4736
+ if (_pluginSettingsRestore) {
4737
+ try {
4738
+ _pluginSettingsRestore();
4739
+ } catch (_e) {
4740
+ // Non-critical
4741
+ }
4742
+ _pluginSettingsRestore = null;
4743
+ }
4744
+
4334
4745
  // Shutdown runtime
4335
4746
  try {
4336
4747
  await shutdown();
@@ -0,0 +1,104 @@
1
+ /**
2
+ * auto-pin policy tests — the OPT-IN compaction pin policy. Verifies it is off
3
+ * by default (returns null → caller passes no predicate → byte-identical), and
4
+ * when enabled pins the original task (first user turn) plus explicit pins,
5
+ * honoring the token cap.
6
+ */
7
+
8
+ import { describe, it, expect } from "vitest";
9
+ import {
10
+ resolveAutoPinConfig,
11
+ buildAutoPinPredicate,
12
+ describeAutoPin,
13
+ } from "../auto-pin.js";
14
+
15
+ const MSGS = [
16
+ { role: "system", content: "you are a coding agent" },
17
+ { role: "user", content: "Refactor the auth module to use async/await" },
18
+ { role: "assistant", content: "ok, reading files" },
19
+ { role: "user", content: "also add tests" },
20
+ ];
21
+
22
+ describe("resolveAutoPinConfig", () => {
23
+ it("returns null when off (falsy)", () => {
24
+ expect(resolveAutoPinConfig(undefined)).toBeNull();
25
+ expect(resolveAutoPinConfig(false)).toBeNull();
26
+ expect(resolveAutoPinConfig(0)).toBeNull();
27
+ });
28
+ it("defaults firstUserGoal on when enabled with true", () => {
29
+ expect(resolveAutoPinConfig(true)).toMatchObject({ firstUserGoal: true });
30
+ });
31
+ it("accepts an object and can disable firstUserGoal", () => {
32
+ expect(resolveAutoPinConfig({ firstUserGoal: false })).toMatchObject({
33
+ firstUserGoal: false,
34
+ });
35
+ expect(resolveAutoPinConfig({ maxPinTokens: 50 }).maxPinTokens).toBe(50);
36
+ });
37
+ });
38
+
39
+ describe("buildAutoPinPredicate", () => {
40
+ it("returns null when auto-pin is off (→ default compaction, byte-identical)", () => {
41
+ expect(buildAutoPinPredicate(MSGS, false)).toBeNull();
42
+ expect(buildAutoPinPredicate(MSGS, undefined)).toBeNull();
43
+ });
44
+
45
+ it("pins the first user turn (the original task) when enabled", () => {
46
+ const isPinned = buildAutoPinPredicate(MSGS, true);
47
+ expect(isPinned(MSGS[1])).toBe(true); // first user
48
+ expect(isPinned(MSGS[3])).toBe(false); // second user NOT pinned
49
+ expect(isPinned(MSGS[0])).toBe(false); // system not pinned
50
+ expect(isPinned(MSGS[2])).toBe(false); // assistant not pinned
51
+ });
52
+
53
+ it("always honors explicit pins on top of the policy", () => {
54
+ const msgs = [
55
+ ...MSGS,
56
+ { role: "assistant", content: "important decision", pinned: true },
57
+ { role: "assistant", content: "legacy marker", _pin: true },
58
+ ];
59
+ const isPinned = buildAutoPinPredicate(msgs, true);
60
+ expect(isPinned(msgs[4])).toBe(true); // pinned:true
61
+ expect(isPinned(msgs[5])).toBe(true); // _pin
62
+ });
63
+
64
+ it("honors explicit pins even with firstUserGoal disabled", () => {
65
+ const msgs = [
66
+ MSGS[0],
67
+ MSGS[1],
68
+ { role: "user", content: "x", pinned: true },
69
+ ];
70
+ const isPinned = buildAutoPinPredicate(msgs, { firstUserGoal: false });
71
+ expect(isPinned(msgs[1])).toBe(false); // first user NOT auto-pinned
72
+ expect(isPinned(msgs[2])).toBe(true); // explicit pin still honored
73
+ });
74
+
75
+ it("skips a first user turn that exceeds the token cap", () => {
76
+ const big = { role: "user", content: "x".repeat(10_000) }; // ~2500 tokens
77
+ const msgs = [MSGS[0], big, MSGS[2]];
78
+ const isPinned = buildAutoPinPredicate(msgs, { maxPinTokens: 100 });
79
+ expect(isPinned(big)).toBe(false); // too big to pin
80
+ });
81
+
82
+ it("matches by identity, not by value (compaction filters the same array)", () => {
83
+ const isPinned = buildAutoPinPredicate(MSGS, true);
84
+ const clone = { ...MSGS[1] }; // same content, different object
85
+ expect(isPinned(clone)).toBe(false);
86
+ });
87
+ });
88
+
89
+ describe("describeAutoPin", () => {
90
+ it("reports disabled when off", () => {
91
+ expect(describeAutoPin(MSGS, false)).toEqual({
92
+ enabled: false,
93
+ reasons: [],
94
+ });
95
+ });
96
+ it("explains the original-task pin", () => {
97
+ const d = describeAutoPin(MSGS, true);
98
+ expect(d.enabled).toBe(true);
99
+ expect(d.reasons.some((r) => r.why.includes("original task"))).toBe(true);
100
+ expect(d.reasons[d.reasons.length - 1].preview).toContain(
101
+ "Refactor the auth",
102
+ );
103
+ });
104
+ });