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
@@ -26,6 +26,7 @@ import {
26
26
  agentLoop as coreAgentLoop,
27
27
  formatToolArgs,
28
28
  killAllBackgroundShellTasks,
29
+ killAllBackgroundShellTasksSync,
29
30
  } from "./agent-core.js";
30
31
  import {
31
32
  resolveAgentMcp,
@@ -315,9 +316,14 @@ export async function runAgentHeadless(options = {}, deps = {}) {
315
316
  const { loadHooks, projectHookTrustNotice } =
316
317
  await import("../lib/settings-hooks.cjs");
317
318
  const loaded = loadHooks({ cwd, settingsFile: options.settingsFile });
319
+ // Fold in installed plugins' hooks/hooks.json (Phase 3.3c) — plugins ADD
320
+ // to the user's settings hooks, never replace them.
321
+ const { mergePluginHooks } =
322
+ await import("../lib/plugin-runtime/hooks.js");
323
+ const effectiveHooks = mergePluginHooks(loaded.hooks, { cwd });
318
324
  settingsHooks =
319
- loaded.hooks && Object.keys(loaded.hooks).length > 0
320
- ? loaded.hooks
325
+ effectiveHooks && Object.keys(effectiveHooks).length > 0
326
+ ? effectiveHooks
321
327
  : null;
322
328
  // First-run trust notice for an untrusted/cloned repo's shell-running
323
329
  // hooks (Claude-Code 2.1.195 parity). Best-effort, stderr-only.
@@ -335,6 +341,26 @@ export async function runAgentHeadless(options = {}, deps = {}) {
335
341
  }
336
342
  }
337
343
 
344
+ // Put trusted plugins' bin/ executables on PATH for this headless run (Phase
345
+ // 3.3n) so run_shell can invoke them by name. Trust-gated. The process exits
346
+ // at the end of the run, so no explicit restore is needed.
347
+ try {
348
+ const { applyPluginBinPath } = await import("../lib/plugin-runtime/bin.js");
349
+ applyPluginBinPath({ cwd });
350
+ } catch {
351
+ /* best-effort — plugin bin PATH never blocks a headless run */
352
+ }
353
+
354
+ // Apply trusted plugins' default env vars for this run (Phase 3.3o) — only for
355
+ // keys not already set; the process exits at the end so no restore is needed.
356
+ try {
357
+ const { applyPluginSettingsEnv } =
358
+ await import("../lib/plugin-runtime/settings.js");
359
+ applyPluginSettingsEnv({ cwd });
360
+ } catch {
361
+ /* best-effort — plugin settings never block a headless run */
362
+ }
363
+
338
364
  // autoMode.classifyAllShell (Claude-Code 2.1.193): route the built-in
339
365
  // verification allowlist through the shell-policy classifier instead of
340
366
  // fast-pathing it. Explicit option wins; otherwise read settings.json.
@@ -668,6 +694,31 @@ export async function runAgentHeadless(options = {}, deps = {}) {
668
694
  }
669
695
  }
670
696
 
697
+ // settings.json SessionResume hooks: fire when a persisted session's prior
698
+ // history is actually being replayed (--resume / --continue with real
699
+ // history), distinct from SessionStart (which also fires on a fresh startup).
700
+ // A SessionResume hook can react to "we're picking an existing conversation
701
+ // back up" — e.g. re-run a workspace sanity check. Observe-only, best-effort.
702
+ if (settingsHooks && resumeId && history.length > 0) {
703
+ try {
704
+ const { runObserveHooks } =
705
+ await import("../lib/settings-hook-events.cjs");
706
+ runObserveHooks(
707
+ settingsHooks,
708
+ "SessionResume",
709
+ {
710
+ session_id: sessionId,
711
+ resumed_from: resumeId,
712
+ history_messages: history.length,
713
+ cwd,
714
+ },
715
+ { cwd },
716
+ );
717
+ } catch (_err) {
718
+ // observe-only
719
+ }
720
+ }
721
+
671
722
  // --image <path>: attach vision input to the user turn. buildUserContent
672
723
  // returns the plain string when there are no images, so text-only runs are
673
724
  // byte-for-byte unchanged; with images it builds an OpenAI-style multimodal
@@ -810,9 +861,40 @@ export async function runAgentHeadless(options = {}, deps = {}) {
810
861
  }
811
862
  }
812
863
 
864
+ // --otlp <file>: attach an OpenTelemetry recorder so the real agent loop's
865
+ // model/tool/retry spans are captured and exported as OTLP/JSON on exit.
866
+ // Off by default (zero cost) — only built when a path is requested.
867
+ let _otlpRecorder = null;
868
+ if (options.otlp) {
869
+ try {
870
+ const { TelemetryRecorder } =
871
+ await import("../lib/telemetry/span-recorder.js");
872
+ _otlpRecorder = new TelemetryRecorder({ serviceName: "cc-agent" });
873
+ } catch {
874
+ _otlpRecorder = null; // telemetry is best-effort, never blocks the run
875
+ }
876
+ }
877
+
878
+ // Async-hook supervisor for headless: without one, `async:true` hooks
879
+ // (PostToolUse / Stop) were silently skipped in `cc agent -p` (they only ran
880
+ // in the REPL). Create one when settings hooks are present so background
881
+ // checks run + get reaped here too. Fire-and-forget; drained after the loop.
882
+ let _hookSupervisor = null;
883
+ if (settingsHooks) {
884
+ try {
885
+ const { AsyncHookSupervisor } =
886
+ await import("../lib/async-hook-supervisor.cjs");
887
+ _hookSupervisor = new AsyncHookSupervisor();
888
+ } catch {
889
+ _hookSupervisor = null; // async hooks are best-effort
890
+ }
891
+ }
892
+
813
893
  const loopOptions = {
814
894
  model,
815
895
  provider,
896
+ recorder: _otlpRecorder,
897
+ hookSupervisor: _hookSupervisor,
816
898
  // Extended thinking (Anthropic; opt-in via --think/--ultrathink). null/off
817
899
  // → chatWithTools sends no thinking field. thinkingBudget (--thinking-budget)
818
900
  // is the legacy-model budget_tokens override; ignored when thinking is off.
@@ -824,6 +906,11 @@ export async function runAgentHeadless(options = {}, deps = {}) {
824
906
  additionalDirectories,
825
907
  sandbox: options.sandbox || null,
826
908
  sessionId,
909
+ // Auto-pin (OPT-IN, off by default): pin the original task through
910
+ // compaction. Enable via --auto-pin or CC_AUTO_PIN=1. Falsy → agent-core
911
+ // passes no pin predicate and compaction is byte-identical.
912
+ autoPin:
913
+ options.autoPin === true || process.env.CC_AUTO_PIN === "1" || undefined,
827
914
  autoCheckpoint: options.autoCheckpoint || false,
828
915
  checkpointSession: options.checkpointSession || sessionId,
829
916
  hookDb: db,
@@ -950,126 +1037,248 @@ export async function runAgentHeadless(options = {}, deps = {}) {
950
1037
  goal_id: boundGoalId,
951
1038
  });
952
1039
 
1040
+ // --auto-rewake: after a turn finishes, run the async Stop hooks and, if an
1041
+ // `asyncRewake` check FAILED, append its report as a new user turn and re-run
1042
+ // the agent to fix it — bounded by `maxRewakes` (default 1). OPT-IN: when off
1043
+ // (the default), rewakeBudget is 0 and the loop below runs exactly once, so
1044
+ // one-shot `cc agent -p` behavior is byte-for-byte unchanged and no script is
1045
+ // surprised by a silent re-run. `_asyncStopHandled` tells the finally the
1046
+ // async Stop hooks already fired here so they aren't fired twice.
1047
+ const autoRewake = options.autoRewake === true;
1048
+ let rewakeBudget = autoRewake
1049
+ ? Number.isFinite(options.maxRewakes)
1050
+ ? options.maxRewakes
1051
+ : 1
1052
+ : 0;
1053
+ let _asyncStopHandled = false;
1054
+ const _settleAsyncStop = async () => {
1055
+ if (!settingsHooks || !_hookSupervisor) return { rewakes: [], results: [] };
1056
+ const { dispatchAsyncHooks } =
1057
+ await import("../lib/settings-hook-events.cjs");
1058
+ dispatchAsyncHooks(
1059
+ settingsHooks,
1060
+ "Stop",
1061
+ { reason: endReason, cwd, session_id: sessionId },
1062
+ { cwd, supervisor: _hookSupervisor },
1063
+ );
1064
+ const waitMs = Number.isFinite(options.asyncHookWaitMs)
1065
+ ? options.asyncHookWaitMs
1066
+ : 5000;
1067
+ const started = Date.now();
1068
+ while (
1069
+ _hookSupervisor.runningCount() > 0 &&
1070
+ Date.now() - started < waitMs
1071
+ ) {
1072
+ await new Promise((r) => setTimeout(r, 50));
1073
+ }
1074
+ return {
1075
+ rewakes: _hookSupervisor.drainRewakes(),
1076
+ results: _hookSupervisor.drainResults(),
1077
+ };
1078
+ };
1079
+
1080
+ // A Ctrl-C (SIGINT) / SIGTERM terminates Node WITHOUT unwinding the `finally`
1081
+ // below, so its background-task reaper is bypassed — a backgrounded run_shell
1082
+ // task (e.g. a dev server) this run spawned would be orphaned. Install a
1083
+ // scoped handler that reaps it synchronously + stops the async-hook
1084
+ // supervisor, then exits with the conventional 128+signal code. Headless has
1085
+ // no other SIGINT owner (no raw-mode keypress like the REPL), so this can't
1086
+ // race a competing handler. Removed in `finally` so a normal return leaves no
1087
+ // listener behind (runAgentHeadless can be called repeatedly in one process).
1088
+ const _onHardSignal = (sig) => {
1089
+ try {
1090
+ killAllBackgroundShellTasksSync();
1091
+ } catch {
1092
+ /* best-effort — never let cleanup throw during shutdown */
1093
+ }
1094
+ try {
1095
+ if (_hookSupervisor) _hookSupervisor.stopAll();
1096
+ } catch {
1097
+ /* best-effort */
1098
+ }
1099
+ process.exit(sig === "SIGTERM" ? 143 : 130);
1100
+ };
1101
+ process.once("SIGINT", _onHardSignal);
1102
+ process.once("SIGTERM", _onHardSignal);
1103
+
953
1104
  try {
954
- for await (const event of runLoop(messages, loopOptions)) {
955
- switch (event.type) {
956
- case "checkpoint": {
957
- if (isText)
958
- writeErr(` ⎌ checkpoint ${event.id} (before ${event.tool})\n`);
959
- emitStream({ type: "checkpoint", id: event.id, tool: event.tool });
960
- break;
961
- }
962
- case "tool-executing": {
963
- const line = ` [${event.tool}] ${formatToolArgs(event.tool, event.args)}`;
964
- if (isText) writeErr(line + "\n");
965
- emitStream({
966
- type: "tool_use",
967
- tool: event.tool,
968
- args: event.args,
969
- });
970
- toolCalls.push({ tool: event.tool, args: event.args });
971
- break;
972
- }
973
- case "tool-result": {
974
- const err = event.error || event.result?.error || null;
975
- if (isText && err) writeErr(` Error: ${err}\n`);
976
- emitStream({
977
- type: "tool_result",
978
- tool: event.tool,
979
- is_error: Boolean(err),
980
- error: err,
981
- result: event.result,
982
- });
983
- if (toolCalls.length > 0) {
984
- toolCalls[toolCalls.length - 1].is_error = Boolean(err);
1105
+ // eslint-disable-next-line no-constant-condition
1106
+ while (true) {
1107
+ for await (const event of runLoop(messages, loopOptions)) {
1108
+ switch (event.type) {
1109
+ case "checkpoint": {
1110
+ if (isText)
1111
+ writeErr(` ⎌ checkpoint ${event.id} (before ${event.tool})\n`);
1112
+ emitStream({ type: "checkpoint", id: event.id, tool: event.tool });
1113
+ break;
985
1114
  }
986
- // Track policy denials (not plain tool failures) for the end-of-run
987
- // summary. The preceding tool-executing pushed the args.
988
- if (err) {
989
- const last = toolCalls[toolCalls.length - 1];
990
- const denial = classifyDenial({
1115
+ case "tool-executing": {
1116
+ const line = ` [${event.tool}] ${formatToolArgs(event.tool, event.args)}`;
1117
+ if (isText) writeErr(line + "\n");
1118
+ emitStream({
1119
+ type: "tool_use",
991
1120
  tool: event.tool,
1121
+ args: event.args,
1122
+ });
1123
+ toolCalls.push({ tool: event.tool, args: event.args });
1124
+ break;
1125
+ }
1126
+ case "tool-result": {
1127
+ const err = event.error || event.result?.error || null;
1128
+ if (isText && err) writeErr(` Error: ${err}\n`);
1129
+ emitStream({
1130
+ type: "tool_result",
1131
+ tool: event.tool,
1132
+ is_error: Boolean(err),
1133
+ error: err,
992
1134
  result: event.result,
993
- error: event.error,
994
- argsSummary:
995
- last && last.tool === event.tool
996
- ? formatToolArgs(event.tool, last.args)
997
- : "",
998
1135
  });
999
- if (denial) {
1000
- recordDenial(denials, {
1001
- ...denial,
1002
- at: deps.now ? deps.now() : Date.now(),
1136
+ if (toolCalls.length > 0) {
1137
+ toolCalls[toolCalls.length - 1].is_error = Boolean(err);
1138
+ }
1139
+ // Track policy denials (not plain tool failures) for the end-of-run
1140
+ // summary. The preceding tool-executing pushed the args.
1141
+ if (err) {
1142
+ const last = toolCalls[toolCalls.length - 1];
1143
+ const denial = classifyDenial({
1144
+ tool: event.tool,
1145
+ result: event.result,
1146
+ error: event.error,
1147
+ argsSummary:
1148
+ last && last.tool === event.tool
1149
+ ? formatToolArgs(event.tool, last.args)
1150
+ : "",
1003
1151
  });
1152
+ if (denial) {
1153
+ recordDenial(denials, {
1154
+ ...denial,
1155
+ at: deps.now ? deps.now() : Date.now(),
1156
+ });
1157
+ }
1004
1158
  }
1159
+ break;
1005
1160
  }
1006
- break;
1007
- }
1008
- case "token-usage": {
1009
- usage.input_tokens += event.usage?.input_tokens || 0;
1010
- usage.output_tokens += event.usage?.output_tokens || 0;
1011
- // Carry prompt-cache tokens into accumulated usage (cost accuracy).
1012
- usage.cache_read_input_tokens +=
1013
- event.usage?.cache_read_input_tokens || 0;
1014
- usage.cache_creation_input_tokens +=
1015
- event.usage?.cache_creation_input_tokens || 0;
1016
- emitStream({ type: "token_usage", usage: event.usage });
1017
- if (costBudget) {
1018
- costBudget.add({
1019
- provider: event.provider,
1020
- model: event.model,
1021
- usage: event.usage,
1022
- });
1023
- if (costBudget.shouldWarnInactive()) {
1024
- const m = `cost cap $${options.maxCostUsd} set but model "${event.model}" is unpriced/free — cap inactive`;
1025
- if (isText) writeErr(` ${m}\n`);
1026
- emitStream({ type: "cost_warning", message: m });
1027
- }
1028
- if (costBudget.exceeded()) {
1029
- endReason = "cost-budget-exhausted";
1030
- stopForCost = true;
1031
- if (isText)
1032
- writeErr(
1033
- ` ⛔ cost budget $${options.maxCostUsd} reached (spent ≈$${costBudget.spentUsd}) — stopping\n`,
1034
- );
1035
- emitStream({
1036
- type: "cost_budget_exhausted",
1037
- limit_usd: options.maxCostUsd,
1038
- spent_usd: costBudget.spentUsd,
1161
+ case "token-usage": {
1162
+ usage.input_tokens += event.usage?.input_tokens || 0;
1163
+ usage.output_tokens += event.usage?.output_tokens || 0;
1164
+ // Carry prompt-cache tokens into accumulated usage (cost accuracy).
1165
+ usage.cache_read_input_tokens +=
1166
+ event.usage?.cache_read_input_tokens || 0;
1167
+ usage.cache_creation_input_tokens +=
1168
+ event.usage?.cache_creation_input_tokens || 0;
1169
+ emitStream({ type: "token_usage", usage: event.usage });
1170
+ if (costBudget) {
1171
+ costBudget.add({
1172
+ provider: event.provider,
1173
+ model: event.model,
1174
+ usage: event.usage,
1039
1175
  });
1176
+ if (costBudget.shouldWarnInactive()) {
1177
+ const m = `cost cap $${options.maxCostUsd} set but model "${event.model}" is unpriced/free — cap inactive`;
1178
+ if (isText) writeErr(` ${m}\n`);
1179
+ emitStream({ type: "cost_warning", message: m });
1180
+ }
1181
+ if (costBudget.exceeded()) {
1182
+ endReason = "cost-budget-exhausted";
1183
+ stopForCost = true;
1184
+ if (isText)
1185
+ writeErr(
1186
+ ` ⛔ cost budget $${options.maxCostUsd} reached (spent ≈$${costBudget.spentUsd}) — stopping\n`,
1187
+ );
1188
+ emitStream({
1189
+ type: "cost_budget_exhausted",
1190
+ limit_usd: options.maxCostUsd,
1191
+ spent_usd: costBudget.spentUsd,
1192
+ });
1193
+ }
1040
1194
  }
1195
+ break;
1196
+ }
1197
+ case "iteration-warning": {
1198
+ if (isText) writeErr(` ${event.message}\n`);
1199
+ emitStream({ type: "iteration_warning", message: event.message });
1200
+ break;
1201
+ }
1202
+ case "iteration-budget-exhausted": {
1203
+ endReason = "max_turns";
1204
+ emitStream({
1205
+ type: "iteration_budget_exhausted",
1206
+ budget: event.budget,
1207
+ });
1208
+ break;
1209
+ }
1210
+ case "response-complete": {
1211
+ finalText = event.content || "";
1212
+ break;
1213
+ }
1214
+ case "run-ended": {
1215
+ if (event.reason) endReason = event.reason;
1216
+ break;
1041
1217
  }
1042
- break;
1218
+ default:
1219
+ // slot-filling, run-started, etc. — surfaced only in stream mode.
1220
+ if (isStream && event.type) emitStream(event);
1221
+ break;
1043
1222
  }
1044
- case "iteration-warning": {
1045
- if (isText) writeErr(` ${event.message}\n`);
1046
- emitStream({ type: "iteration_warning", message: event.message });
1047
- break;
1223
+ // Hard cost cap reached: stop consuming the loop so no further paid LLM
1224
+ // call is made (break out of the for-await, not just the switch).
1225
+ if (stopForCost) break;
1226
+ }
1227
+ // ── auto-rewake re-drive (opt-in via --auto-rewake) ─────────────────
1228
+ // Under auto-rewake, settle the async Stop hooks after EVERY turn (so the
1229
+ // final turn's background check still runs). If an asyncRewake check
1230
+ // failed and re-drive budget remains, append its report as a new user
1231
+ // turn and loop; if a rewake failed but budget is spent, surface it and
1232
+ // stop. When auto-rewake is off, this whole block is skipped and the
1233
+ // `finally` handles Stop exactly as before (default behavior unchanged).
1234
+ if (
1235
+ autoRewake &&
1236
+ _hookSupervisor &&
1237
+ !stopForCost &&
1238
+ endReason !== "max_turns" &&
1239
+ endReason !== "cost-budget-exhausted"
1240
+ ) {
1241
+ const { rewakes, results } = await _settleAsyncStop();
1242
+ _asyncStopHandled = true;
1243
+ for (const rs of results) {
1244
+ if (rs.additionalContext)
1245
+ writeErr(`[async-hook] ${rs.command}: ${rs.additionalContext}\n`);
1048
1246
  }
1049
- case "iteration-budget-exhausted": {
1050
- endReason = "max_turns";
1051
- emitStream({
1052
- type: "iteration_budget_exhausted",
1053
- budget: event.budget,
1247
+ if (rewakes.length > 0 && rewakeBudget > 0) {
1248
+ rewakeBudget--;
1249
+ const detail = rewakes
1250
+ .map(
1251
+ (rw) =>
1252
+ `- ${rw.command} failed` +
1253
+ `${rw.exitCode != null ? ` (exit ${rw.exitCode})` : ""}` +
1254
+ `${rw.error ? `: ${rw.error}` : ""}`,
1255
+ )
1256
+ .join("\n");
1257
+ messages.push({
1258
+ role: "user",
1259
+ content:
1260
+ `A background check flagged a problem after your last turn:\n${detail}\n` +
1261
+ `Investigate and fix it, then confirm it passes.`,
1054
1262
  });
1055
- break;
1056
- }
1057
- case "response-complete": {
1058
- finalText = event.content || "";
1059
- break;
1263
+ if (isText)
1264
+ writeErr(
1265
+ ` ↻ async-hook rewake — re-engaging agent (${rewakeBudget} re-drive(s) left)\n`,
1266
+ );
1267
+ emitStream({ type: "rewake", remaining: rewakeBudget });
1268
+ finalText = "";
1269
+ endReason = "complete";
1270
+ continue; // re-drive: run another agent turn
1060
1271
  }
1061
- case "run-ended": {
1062
- if (event.reason) endReason = event.reason;
1063
- break;
1272
+ // A rewake fired but no budget remains — surface it (couldn't auto-fix).
1273
+ for (const rw of rewakes) {
1274
+ writeErr(
1275
+ `[async-hook REWAKE] ${rw.command} failed` +
1276
+ `${rw.exitCode != null ? ` (exit ${rw.exitCode})` : ""}` +
1277
+ `${rw.error ? `: ${rw.error}` : ""}\n`,
1278
+ );
1064
1279
  }
1065
- default:
1066
- // slot-filling, run-started, etc. — surfaced only in stream mode.
1067
- if (isStream && event.type) emitStream(event);
1068
- break;
1069
1280
  }
1070
- // Hard cost cap reached: stop consuming the loop so no further paid LLM
1071
- // call is made (break out of the for-await, not just the switch).
1072
- if (stopForCost) break;
1281
+ break;
1073
1282
  }
1074
1283
  } catch (err) {
1075
1284
  const message = err?.message || String(err);
@@ -1101,6 +1310,11 @@ export async function runAgentHeadless(options = {}, deps = {}) {
1101
1310
  }
1102
1311
  return { exitCode: 1, result: message, isError: true };
1103
1312
  } finally {
1313
+ // Drop the signal handlers first — a normal return must not leave a
1314
+ // process-wide SIGINT/SIGTERM listener behind (a later Ctrl-C would wrongly
1315
+ // exit with 130, and repeated in-process runs would leak listeners).
1316
+ process.removeListener("SIGINT", _onHardSignal);
1317
+ process.removeListener("SIGTERM", _onHardSignal);
1104
1318
  // Tear down ad-hoc MCP servers (--mcp-config) before returning, whether the
1105
1319
  // loop completed or threw. Best-effort: a failed disconnect never masks the
1106
1320
  // run's own outcome.
@@ -1118,11 +1332,56 @@ export async function runAgentHeadless(options = {}, deps = {}) {
1118
1332
  } catch {
1119
1333
  // best-effort — never mask the run's own outcome
1120
1334
  }
1121
- // settings.json SessionEnd hooks (observe-only) when the run finishes.
1335
+ // settings.json Stop + SessionEnd hooks when the run finishes. Stop is the
1336
+ // canonical async-hook trigger ("run the test suite at turn end"); fire its
1337
+ // async hooks fire-and-forget, then settle so a fast background check can
1338
+ // report back within this one-shot run.
1122
1339
  if (settingsHooks) {
1123
1340
  try {
1124
- const { runObserveHooks } =
1341
+ const { runObserveHooks, dispatchAsyncHooks } =
1125
1342
  await import("../lib/settings-hook-events.cjs");
1343
+ const stopPayload = { reason: endReason, cwd, session_id: sessionId };
1344
+ runObserveHooks(settingsHooks, "Stop", stopPayload, { cwd });
1345
+ // Skip the async Stop dispatch/settle here if the auto-rewake re-drive
1346
+ // loop already fired + drained it this run (avoids double-execution).
1347
+ if (_hookSupervisor && !_asyncStopHandled) {
1348
+ dispatchAsyncHooks(settingsHooks, "Stop", stopPayload, {
1349
+ cwd,
1350
+ supervisor: _hookSupervisor,
1351
+ });
1352
+ // Bounded settle: wait for in-flight async hooks (Stop + any
1353
+ // PostToolUse dispatched during the loop) to finish, capped so a
1354
+ // slow/hung check can never stall the run. Default 5s; tunable.
1355
+ const waitMs = Number.isFinite(options.asyncHookWaitMs)
1356
+ ? options.asyncHookWaitMs
1357
+ : 5000;
1358
+ const started = Date.now();
1359
+ while (
1360
+ _hookSupervisor.runningCount() > 0 &&
1361
+ Date.now() - started < waitMs
1362
+ ) {
1363
+ await new Promise((r) => setTimeout(r, 50));
1364
+ }
1365
+ // Surface any results/rewakes out-of-band on stderr (never touches the
1366
+ // stdout envelope). A rewake means a background check FAILED and would
1367
+ // re-engage the agent in an interactive session — flag it clearly so a
1368
+ // headless caller/CI can react.
1369
+ for (const rw of _hookSupervisor.drainRewakes()) {
1370
+ writeErr(
1371
+ `[async-hook REWAKE] ${rw.command} failed` +
1372
+ `${rw.exitCode != null ? ` (exit ${rw.exitCode})` : ""}` +
1373
+ `${rw.error ? `: ${rw.error}` : ""}\n`,
1374
+ );
1375
+ }
1376
+ for (const rs of _hookSupervisor.drainResults()) {
1377
+ if (rs.additionalContext) {
1378
+ writeErr(`[async-hook] ${rs.command}: ${rs.additionalContext}\n`);
1379
+ }
1380
+ }
1381
+ }
1382
+ // Always reap the supervisor (kills any straggler child + detaches the
1383
+ // exit reaper), whether the async Stop was handled here or in re-drive.
1384
+ if (_hookSupervisor) _hookSupervisor.stopAll();
1126
1385
  runObserveHooks(
1127
1386
  settingsHooks,
1128
1387
  "SessionEnd",
@@ -1130,7 +1389,7 @@ export async function runAgentHeadless(options = {}, deps = {}) {
1130
1389
  { cwd },
1131
1390
  );
1132
1391
  } catch {
1133
- // observe-only
1392
+ // observe-only + best-effort async surfacing
1134
1393
  }
1135
1394
  }
1136
1395
  }
@@ -1259,6 +1518,27 @@ export async function runAgentHeadless(options = {}, deps = {}) {
1259
1518
  writeOut(finalText + (finalText.endsWith("\n") ? "" : "\n"));
1260
1519
  }
1261
1520
 
1521
+ // --otlp: write the captured spans/counters as OTLP/JSON. Best-effort — a
1522
+ // write failure logs to stderr but never changes the run's exit code.
1523
+ if (_otlpRecorder && options.otlp) {
1524
+ try {
1525
+ const fsp = await import("node:fs");
1526
+ fsp.writeFileSync(
1527
+ options.otlp,
1528
+ JSON.stringify(_otlpRecorder.toOtlp(), null, 2),
1529
+ "utf-8",
1530
+ );
1531
+ if (!isStream) {
1532
+ const sum = _otlpRecorder.summary();
1533
+ process.stderr.write(
1534
+ `[otlp] ${sum.spanCount} span(s) → ${options.otlp}\n`,
1535
+ );
1536
+ }
1537
+ } catch (err) {
1538
+ process.stderr.write(`[otlp] export failed: ${err.message}\n`);
1539
+ }
1540
+ }
1541
+
1262
1542
  return { exitCode: isError ? 1 : 0, result: finalText, isError };
1263
1543
  }
1264
1544
 
@@ -33,6 +33,7 @@ import {
33
33
  jetbrainsServerToMcpConfig,
34
34
  isInJetbrainsContext,
35
35
  } from "../lib/jetbrains-bridge.js";
36
+ import { collectPluginMcpServers } from "../lib/plugin-runtime/mcp.js";
36
37
 
37
38
  /**
38
39
  * Normalize a parsed config object into a `{ name: serverConfig }` map.
@@ -644,6 +645,39 @@ export async function loadProjectMcp(opts = {}, deps = {}) {
644
645
  return setupMcpFromConfig(servers, deps);
645
646
  }
646
647
 
648
+ /**
649
+ * Load MCP servers declared by installed plugins' `.mcp.json` (Phase 3.3g —
650
+ * plugin MCP component reaches the agent's tool surface).
651
+ *
652
+ * Unlike a project `.mcp.json` (opt-in via --project-mcp because ANY cloned repo
653
+ * can carry one), plugin MCP servers load by default: installing AND trusting a
654
+ * plugin IS the explicit user action. `collectPluginMcpServers` already trust-
655
+ * gates — only user/local-scope plugins and `cc plugin trust`-ed project plugins
656
+ * contribute — so a server never spawns from an untrusted cloned-repo plugin.
657
+ *
658
+ * Chains onto `deps.into` after the registered + project servers, so those win
659
+ * on a name clash (the plugin ADDS servers without overriding the user's own).
660
+ *
661
+ * @param {object} opts { cwd, scopes }
662
+ * @param {object} [deps] { collect, writeErr, into, ... setupMcpFromConfig deps }
663
+ */
664
+ export async function loadPluginMcp(opts = {}, deps = {}) {
665
+ const collect = deps.collect || collectPluginMcpServers;
666
+ const writeErr = deps.writeErr || (() => {});
667
+ let servers = {};
668
+ try {
669
+ ({ servers } = collect({ cwd: opts.cwd, scopes: opts.scopes }));
670
+ } catch {
671
+ return deps.into || null;
672
+ }
673
+ const names = Object.keys(servers || {});
674
+ if (names.length === 0) return deps.into || null;
675
+ writeErr(
676
+ ` mcp: ${names.length} server(s) from trusted plugin(s): ${names.join(", ")}\n`,
677
+ );
678
+ return setupMcpFromConfig(servers, deps);
679
+ }
680
+
647
681
  /**
648
682
  * Resolve the full MCP tool surface for one agent run: the ad-hoc
649
683
  * `--mcp-config` file (if any) PLUS registered auto-connect servers (unless
@@ -665,6 +699,7 @@ export async function resolveAgentMcp(args = {}, deps = {}) {
665
699
  const doFile = deps.loadMcpConfig || loadMcpConfig;
666
700
  const doReg = deps.loadRegisteredMcp || loadRegisteredMcp;
667
701
  const doProject = deps.loadProjectMcp || loadProjectMcp;
702
+ const doPlugin = deps.loadPluginMcp || loadPluginMcp;
668
703
  const doIde = deps.loadIdeMcp || loadIdeMcp;
669
704
  const doPdh = deps.loadPdhMcp || loadPdhMcp;
670
705
  const doJetbrains = deps.loadJetbrainsMcp || loadJetbrainsMcp;
@@ -712,6 +747,17 @@ export async function resolveAgentMcp(args = {}, deps = {}) {
712
747
  { ...fwd, into: result || undefined },
713
748
  );
714
749
  }
750
+ // Installed-plugin `.mcp.json` servers (Claude-Code parity). Loads by default
751
+ // (no opt-in flag): unlike a project `.mcp.json`, a plugin only contributes
752
+ // when it is installed AND trusted (trust-gated inside collectPluginMcpServers)
753
+ // — that install+trust IS the explicit consent. Registered + project servers
754
+ // above win on a name clash. `pluginMcp:false` hard-skips it.
755
+ if (args.pluginMcp !== false) {
756
+ result = await doPlugin(
757
+ { cwd: args.cwd, scopes: args.pluginScopes },
758
+ { ...fwd, into: result || undefined },
759
+ );
760
+ }
715
761
  if (args.ide !== false) {
716
762
  const env = args.env || process.env;
717
763
  const inIde = (deps.isInIdeTerminal || isInIdeTerminal)(env);
@@ -1 +0,0 @@
1
- import{I as v,P as u,J as y,U as n,R as a,S,K as C,Q as w,V as x,_ as B,b as s}from"./vendor-BMxUs6UX.js";import{_ as k}from"./index-BtbbdLnf.js";import"./icons-BsDmGpcT.js";const N={__name:"ChatBubbleRenderer",props:{event:{type:Object,required:!0}},setup(c,{expose:d}){d();const t=c,r=s(()=>{const e=t.event.content||{};return e.text||e.body||e.message||e.title||JSON.stringify(e).slice(0,200)}),i=s(()=>{const e=t.event.content||{};return e.from||e.sender||e.senderName||t.event.actor||"(unknown)"}),l=s(()=>{const e=(t.event.actor||"").toLowerCase();return e.includes("self")||e==="me"||e.endsWith("_self")}),o=s(()=>{const e=t.event.source.adapter||"";return e.startsWith("messaging-qq")?"magenta":e==="wechat"?"green":"blue"}),m=s(()=>{if(!t.event.occurredAt)return"";try{const e=new Date(t.event.occurredAt),p=e.getFullYear(),b=String(e.getMonth()+1).padStart(2,"0"),f=String(e.getDate()).padStart(2,"0"),g=String(e.getHours()).padStart(2,"0"),h=String(e.getMinutes()).padStart(2,"0");return`${p}-${b}-${f} ${g}:${h}`}catch{return""}}),_={props:t,messageText:r,actorLabel:i,isMine:l,adapterColor:o,formattedTime:m,computed:s};return Object.defineProperty(_,"__isScriptSetup",{enumerable:!1,value:!0}),_}},T={class:"bubble"},M={class:"meta"},R={class:"actor"},V={class:"time"},q={class:"body"};function D(c,d,t,r,i,l){const o=v("a-tag");return u(),y("div",{class:B(["chat-row",{mine:r.isMine}])},[n("div",T,[n("div",M,[n("span",R,a(r.actorLabel),1),n("span",V,a(r.formattedTime),1)]),n("div",q,a(r.messageText),1),t.event.source.adapter?(u(),S(o,{key:0,class:"src",color:r.adapterColor},{default:C(()=>[w(a(t.event.source.adapter),1)]),_:1},8,["color"])):x("v-if",!0)])],2)}const A=k(N,[["render",D],["__scopeId","data-v-49238629"],["__file","/tmp/cc-web-panel-w66Hyb/repo/packages/web-panel/src/components/pdh/renderers/ChatBubbleRenderer.vue"]]);export{A as default};