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
@@ -0,0 +1,165 @@
1
+ /**
2
+ * TeamBudget (Phase 4 — Agent Team) — a team-wide spend cap across four
3
+ * independent dimensions, consulted by TeamRunner BEFORE it hands a teammate a
4
+ * new task so a runaway graph is bounded and a resumed session keeps counting
5
+ * from where it left off (Phase 4 acceptance "支持 token、时间、并发数和费用预算"
6
+ * + "团队会话恢复后…预算保持一致").
7
+ *
8
+ * - maxTasks total task EXECUTIONS across all teammates (task-count cap)
9
+ * - maxTokens total (input+output) LLM tokens folded from task results
10
+ * - maxUsd total estimated USD spend — delegated to the audited CostBudget
11
+ * (same pricing/cache-token rules as `--max-budget-usd`)
12
+ * - maxWallMs wall-clock since the first task started (time cap)
13
+ *
14
+ * Because a task's cost is only known once it returns, the team may overshoot a
15
+ * token/USD cap by at most one task — like CostBudget, it never STARTS a task
16
+ * once already over. A dimension left null is simply inactive. The clock is
17
+ * injected so the wall-clock cap is deterministic in tests, and snapshot/restore
18
+ * carries the running totals so `cc team run --resume` doesn't reset the budget.
19
+ */
20
+
21
+ import { CostBudget } from "../cost-budget.js";
22
+
23
+ const pos = (n) => {
24
+ const v = Number(n);
25
+ return Number.isFinite(v) && v > 0 ? v : null;
26
+ };
27
+
28
+ export class TeamBudget {
29
+ constructor({
30
+ maxTasks = null,
31
+ maxTokens = null,
32
+ maxUsd = null,
33
+ maxWallMs = null,
34
+ table = undefined,
35
+ now = () => Date.now(),
36
+ } = {}) {
37
+ this._now = typeof now === "function" ? now : () => now;
38
+ this.maxTasks = pos(maxTasks);
39
+ this.maxTokens = pos(maxTokens);
40
+ this.maxWallMs = pos(maxWallMs);
41
+ this.cost = new CostBudget({ limitUsd: maxUsd, table });
42
+ this.tasks = 0;
43
+ this.tokens = 0;
44
+ this.startedAt = null; // set on the first recorded task
45
+ }
46
+
47
+ /** Any dimension active? (an all-null budget never stops anything). */
48
+ enabled() {
49
+ return (
50
+ this.maxTasks != null ||
51
+ this.maxTokens != null ||
52
+ this.maxWallMs != null ||
53
+ this.cost.enabled()
54
+ );
55
+ }
56
+
57
+ /** Begin the wall-clock window (idempotent — first call wins). */
58
+ start(now = this._now()) {
59
+ if (this.startedAt == null) this.startedAt = now;
60
+ return this;
61
+ }
62
+
63
+ /**
64
+ * Fold one settled task into the running totals. `usage` (an LLM token-usage
65
+ * event) is optional — a plain `--exec` shell task carries none, so only the
66
+ * task-count / wall-clock dimensions move for it.
67
+ * @returns {this}
68
+ */
69
+ record({ usage = null, provider, model } = {}, now = this._now()) {
70
+ this.start(now);
71
+ this.tasks += 1;
72
+ if (usage) {
73
+ this.tokens +=
74
+ (Number(usage.input_tokens) || 0) + (Number(usage.output_tokens) || 0);
75
+ this.cost.add({ provider, model, usage });
76
+ }
77
+ return this;
78
+ }
79
+
80
+ /**
81
+ * Which cap (if any) is now reached — checked BEFORE starting a new task.
82
+ * @returns {null|"max-tasks"|"max-tokens"|"max-usd"|"max-wall-ms"}
83
+ */
84
+ reason(now = this._now()) {
85
+ if (this.maxTasks != null && this.tasks >= this.maxTasks) {
86
+ return "max-tasks";
87
+ }
88
+ if (this.maxTokens != null && this.tokens >= this.maxTokens) {
89
+ return "max-tokens";
90
+ }
91
+ if (this.cost.exceeded()) return "max-usd";
92
+ if (
93
+ this.maxWallMs != null &&
94
+ this.startedAt != null &&
95
+ now - this.startedAt >= this.maxWallMs
96
+ ) {
97
+ return "max-wall-ms";
98
+ }
99
+ return null;
100
+ }
101
+
102
+ /** True once any active cap has been reached. */
103
+ shouldStop(now = this._now()) {
104
+ return this.reason(now) != null;
105
+ }
106
+
107
+ status(now = this._now()) {
108
+ return {
109
+ tasks: this.tasks,
110
+ maxTasks: this.maxTasks,
111
+ tokens: this.tokens,
112
+ maxTokens: this.maxTokens,
113
+ spentUsd: this.cost.spentUsd,
114
+ maxUsd: this.cost.limitUsd,
115
+ elapsedMs: this.startedAt == null ? 0 : now - this.startedAt,
116
+ maxWallMs: this.maxWallMs,
117
+ reason: this.reason(now),
118
+ };
119
+ }
120
+
121
+ snapshot() {
122
+ return {
123
+ limits: {
124
+ maxTasks: this.maxTasks,
125
+ maxTokens: this.maxTokens,
126
+ maxUsd: this.cost.limitUsd,
127
+ maxWallMs: this.maxWallMs,
128
+ },
129
+ totals: {
130
+ tasks: this.tasks,
131
+ tokens: this.tokens,
132
+ spentUsd: this.cost.spentUsd,
133
+ startedAt: this.startedAt,
134
+ },
135
+ };
136
+ }
137
+
138
+ /**
139
+ * Restore running totals + caps from a snapshot. `overrides` lets the current
140
+ * CLI invocation RAISE/lower a cap on resume — a provided (non-nullish) value
141
+ * wins over the snapshot's; an omitted one keeps the prior cap (so a resume
142
+ * with no flags can't silently drop a safety cap).
143
+ */
144
+ static restore(snap, { now = () => Date.now(), table, overrides = {} } = {}) {
145
+ const pick = (o, s) => (o == null ? s : o);
146
+ const b = new TeamBudget({
147
+ maxTasks: pick(overrides.maxTasks, snap?.limits?.maxTasks),
148
+ maxTokens: pick(overrides.maxTokens, snap?.limits?.maxTokens),
149
+ maxUsd: pick(overrides.maxUsd, snap?.limits?.maxUsd),
150
+ maxWallMs: pick(overrides.maxWallMs, snap?.limits?.maxWallMs),
151
+ table,
152
+ now,
153
+ });
154
+ b.tasks = Number(snap?.totals?.tasks) || 0;
155
+ b.tokens = Number(snap?.totals?.tokens) || 0;
156
+ // Preserve prior USD spend so the cap keeps counting across a resume.
157
+ const spent = Number(snap?.totals?.spentUsd);
158
+ b.cost.spentUsd = Number.isFinite(spent) && spent >= 0 ? spent : 0;
159
+ if (b.cost.spentUsd > 0) b.cost.priced = true;
160
+ // A time cap must NOT keep counting wall-clock across a crash gap (the
161
+ // process was down); restart the window on the next recorded task.
162
+ b.startedAt = null;
163
+ return b;
164
+ }
165
+ }
@@ -0,0 +1,106 @@
1
+ /**
2
+ * TeamMailbox (Phase 4 — Agent Team) — directed + broadcast messaging between
3
+ * teammates so a coordinating agent can hand off context, flag a finding, or ask
4
+ * a peer to redo work (Phase 4 work-item "支持 Agent 间直接消息和定向通知",
5
+ * acceptance "团队会话恢复后…消息…保持一致").
6
+ *
7
+ * A message is addressed to a specific recipient (`to`) or broadcast (`to:"*"`).
8
+ * `drain(recipient)` returns that recipient's undelivered messages (direct +
9
+ * broadcasts it hasn't seen) and marks them delivered FOR THAT RECIPIENT — a
10
+ * broadcast is delivered independently to each teammate, so two teammates each
11
+ * receive it exactly once. Delivery cursors + the log are in the snapshot, so a
12
+ * resumed session re-delivers only what a teammate hadn't yet drained.
13
+ *
14
+ * Pure + deterministic: ids come from a monotonic counter (not a clock) and the
15
+ * clock is injected only for timestamps, so ordering is stable in tests.
16
+ */
17
+
18
+ export class TeamMailbox {
19
+ constructor({ now = () => Date.now() } = {}) {
20
+ this._now = typeof now === "function" ? now : () => now;
21
+ this._log = []; // ordered [{ id, from, to, subject, body, ts }]
22
+ this._seq = 0; // monotonic message id source
23
+ this._delivered = new Map(); // recipient → highest message id already drained
24
+ }
25
+
26
+ /**
27
+ * Post a message. `to` is a teammate id or "*" (broadcast). Returns the stored
28
+ * message (with its assigned id).
29
+ */
30
+ send({ from = null, to, subject = null, body = null } = {}) {
31
+ if (!to || typeof to !== "string") {
32
+ throw new Error("TeamMailbox.send: `to` recipient (or '*') is required");
33
+ }
34
+ const msg = {
35
+ id: ++this._seq,
36
+ from,
37
+ to,
38
+ subject,
39
+ body,
40
+ ts: this._now(),
41
+ };
42
+ this._log.push(msg);
43
+ return { ...msg };
44
+ }
45
+
46
+ _isFor(msg, recipient) {
47
+ return msg.to === recipient || msg.to === "*";
48
+ }
49
+
50
+ /** Peek at a recipient's undelivered messages WITHOUT marking them delivered. */
51
+ peek(recipient) {
52
+ const cursor = this._delivered.get(recipient) || 0;
53
+ return this._log
54
+ .filter(
55
+ (m) =>
56
+ m.id > cursor && m.from !== recipient && this._isFor(m, recipient),
57
+ )
58
+ .map((m) => ({ ...m }));
59
+ }
60
+
61
+ /**
62
+ * Return a recipient's undelivered messages and advance its delivery cursor so
63
+ * they are not returned again. A teammate never receives its own broadcast.
64
+ */
65
+ drain(recipient) {
66
+ const pending = this.peek(recipient);
67
+ if (pending.length > 0) {
68
+ const highest = pending[pending.length - 1].id;
69
+ const cursor = this._delivered.get(recipient) || 0;
70
+ this._delivered.set(recipient, Math.max(cursor, highest));
71
+ }
72
+ return pending;
73
+ }
74
+
75
+ /** How many messages a recipient has yet to drain. */
76
+ pendingCount(recipient) {
77
+ return this.peek(recipient).length;
78
+ }
79
+
80
+ /** The full ordered message log (for a status panel / audit). */
81
+ log() {
82
+ return this._log.map((m) => ({ ...m }));
83
+ }
84
+
85
+ size() {
86
+ return this._log.length;
87
+ }
88
+
89
+ snapshot() {
90
+ return {
91
+ log: this._log.map((m) => ({ ...m })),
92
+ seq: this._seq,
93
+ delivered: Array.from(this._delivered.entries()),
94
+ };
95
+ }
96
+
97
+ static restore(snap, { now = () => Date.now() } = {}) {
98
+ const mb = new TeamMailbox({ now });
99
+ mb._log = Array.isArray(snap?.log) ? snap.log.map((m) => ({ ...m })) : [];
100
+ mb._seq =
101
+ Number(snap?.seq) ||
102
+ mb._log.reduce((max, m) => Math.max(max, m.id || 0), 0);
103
+ mb._delivered = new Map(snap?.delivered || []);
104
+ return mb;
105
+ }
106
+ }
@@ -0,0 +1,282 @@
1
+ /**
2
+ * TeamRunner (Phase 4 — Agent Team) — drives a TaskLeaseRegistry with N
3
+ * concurrent teammates, each looping: pick a claimable task → acquire its
4
+ * EXCLUSIVE lease → run it → complete (or fail → retry/cancel). The registry's
5
+ * lease + dependency DAG guarantees the two things a plain worker pool can't:
6
+ * - a task is run by AT MOST ONE teammate at a time (exclusive lease), so no
7
+ * duplicate work even with M teammates racing for the same task;
8
+ * - a task only starts once its dependencies are COMPLETED (DAG gating), and a
9
+ * task whose dependency was CANCELLED never runs (stays blocked).
10
+ *
11
+ * `runTask` is injected so the whole orchestration is unit-testable offline; in
12
+ * production it's wired to a real agent turn (SubAgentContext.run in a
13
+ * per-teammate worktree). Events are emitted for a machine-readable stream /
14
+ * status panel. A total-time / total-task budget bounds a runaway graph.
15
+ */
16
+
17
+ export class TeamRunner {
18
+ /**
19
+ * @param {TaskLeaseRegistry} registry
20
+ * @param {object} opts
21
+ * runTask async ({key, task, holder, renew}) => any (throw = task failed)
22
+ * teammates number of concurrent workers (default 2)
23
+ * ttlMs lease TTL per acquisition
24
+ * onEvent (evt) => void {type, ...}
25
+ * maxTasks safety cap on total task executions (default 1000)
26
+ * now () => ms (for deadline math; defaults to registry clock)
27
+ */
28
+ constructor(registry, opts = {}) {
29
+ this.registry = registry;
30
+ this.runTask = opts.runTask;
31
+ this.teammates = opts.teammates > 0 ? Math.floor(opts.teammates) : 2;
32
+ this.ttlMs = opts.ttlMs;
33
+ this.onEvent = typeof opts.onEvent === "function" ? opts.onEvent : () => {};
34
+ this.maxTasks = opts.maxTasks > 0 ? opts.maxTasks : 1000;
35
+ this._now = opts.now || registry._now || (() => Date.now());
36
+ // Team-wide token/USD/time/task budget (null → unbounded). Consulted before
37
+ // every claim; folded after every settled task.
38
+ this.budget = opts.budget || null;
39
+ // Directed/broadcast messaging between teammates (null → disabled).
40
+ this.mailbox = opts.mailbox || null;
41
+ this._executions = 0;
42
+ this._inFlight = 0;
43
+ this._maxInFlight = 0;
44
+ this._members = new Map(); // holder → lifecycle record
45
+ this._budgetStopped = false;
46
+ }
47
+
48
+ _emit(type, extra) {
49
+ try {
50
+ this.onEvent({ type, ts: this._now(), ...extra });
51
+ } catch {
52
+ /* event sink is best-effort */
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Track a teammate's lifecycle state (idle / running / failed / shutdown) and
58
+ * emit a `teammate:state` event on every transition. `lost` is set on resume
59
+ * by the caller for a teammate whose lease was reclaimed after a crash.
60
+ */
61
+ _setState(holder, state, extra = {}) {
62
+ let m = this._members.get(holder);
63
+ if (!m) {
64
+ m = { holder, state: null, completed: 0, failed: 0, lastError: null };
65
+ this._members.set(holder, m);
66
+ }
67
+ if (state === "completed-task") {
68
+ m.completed += 1;
69
+ return m;
70
+ }
71
+ if (state === "failed-task") {
72
+ m.failed += 1;
73
+ m.lastError = extra.error || null;
74
+ return m;
75
+ }
76
+ if (m.state === state) return m; // no transition
77
+ m.state = state;
78
+ this._emit("teammate:state", { holder, state, ...extra });
79
+ return m;
80
+ }
81
+
82
+ /** Snapshot of every teammate's lifecycle (for a status panel / resume). */
83
+ members() {
84
+ return Array.from(this._members.values()).map((m) => ({ ...m }));
85
+ }
86
+
87
+ /** Restore prior-run member records (e.g. before a --resume run). */
88
+ seedMembers(records = []) {
89
+ for (const r of records) {
90
+ if (r && r.holder) this._members.set(r.holder, { ...r });
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Run the graph to completion (all tasks terminal) or until no teammate can
96
+ * make progress (everything remaining is blocked/leased). Returns a summary.
97
+ */
98
+ async run() {
99
+ if (typeof this.runTask !== "function") {
100
+ throw new Error("TeamRunner: opts.runTask is required");
101
+ }
102
+ this._emit("run:start", {
103
+ teammates: this.teammates,
104
+ tasks: this.registry.list().length,
105
+ });
106
+ if (this.budget) this.budget.start();
107
+ const workers = [];
108
+ for (let i = 0; i < this.teammates; i++) {
109
+ const holder = `teammate-${i + 1}`;
110
+ this._setState(holder, "idle");
111
+ workers.push(this._worker(holder));
112
+ }
113
+ await Promise.all(workers);
114
+ const stats = this.registry.stats();
115
+ const summary = {
116
+ done: this.registry.allDone(),
117
+ executions: this._executions,
118
+ maxConcurrent: this._maxInFlight,
119
+ budgetStopped: this._budgetStopped,
120
+ budgetReason: this.budget ? this.budget.reason() : null,
121
+ members: this.members(),
122
+ messages: this.mailbox ? this.mailbox.size() : 0,
123
+ stats,
124
+ };
125
+ this._emit("run:end", summary);
126
+ return summary;
127
+ }
128
+
129
+ async _worker(holder) {
130
+ // Each teammate keeps taking claimable work until none is left FOR IT. A
131
+ // task blocked only by a peer's in-flight lease will free up (complete) or
132
+ // its dep will finish — so a worker that finds nothing claimable yields and
133
+ // re-checks while any work is still in flight.
134
+ for (;;) {
135
+ if (this._executions >= this.maxTasks) {
136
+ this._emit("run:budget-exhausted", { maxTasks: this.maxTasks });
137
+ this._setState(holder, "shutdown", { reason: "max-tasks" });
138
+ return;
139
+ }
140
+ // Team budget (token/USD/time/task) — stop CLAIMING once any cap is hit so
141
+ // the team overshoots by at most the tasks already in flight.
142
+ if (this.budget && this.budget.shouldStop()) {
143
+ const reason = this.budget.reason();
144
+ if (!this._budgetStopped) {
145
+ this._budgetStopped = true;
146
+ this._emit("run:budget-exhausted", { reason });
147
+ }
148
+ this._setState(holder, "shutdown", { reason });
149
+ return;
150
+ }
151
+ const key = this._nextFor(holder);
152
+ if (!key) {
153
+ // Nothing to claim right now. If peers are still working, wait and
154
+ // retry (their completions may unblock a dependent). Otherwise we're done.
155
+ if (this._inFlight > 0) {
156
+ this._setState(holder, "idle");
157
+ await this._tick();
158
+ continue;
159
+ }
160
+ this._setState(holder, "shutdown", { reason: "no-more-work" });
161
+ return; // no claimable + nothing in flight → this worker is finished
162
+ }
163
+ const acq = this.registry.acquire(key, { holder, ttlMs: this.ttlMs });
164
+ if (!acq.ok) {
165
+ // Lost the race to a peer (or it just got blocked) — try another.
166
+ this._setState(holder, "idle");
167
+ await this._tick();
168
+ continue;
169
+ }
170
+ await this._execute(holder, key, acq.lease);
171
+ }
172
+ }
173
+
174
+ /** Pick a claimable task key for this holder (highest priority first). */
175
+ _nextFor() {
176
+ const claimable = this.registry.claimable();
177
+ if (claimable.length === 0) return null;
178
+ // Stable: prefer higher priority, else insertion order (claimable order).
179
+ const rank = { high: 0, normal: 1, low: 2 };
180
+ let best = null;
181
+ let bestScore = Infinity;
182
+ for (const key of claimable) {
183
+ const t = this.registry.getTask(key);
184
+ const score = rank[t?.priority] ?? 1;
185
+ if (score < bestScore) {
186
+ bestScore = score;
187
+ best = key;
188
+ }
189
+ }
190
+ return best;
191
+ }
192
+
193
+ async _execute(holder, key, lease) {
194
+ const task = this.registry.getTask(key);
195
+ this._executions++;
196
+ this._inFlight++;
197
+ this._maxInFlight = Math.max(this._maxInFlight, this._inFlight);
198
+ this._setState(holder, "running", { key });
199
+ this._emit("task:claimed", { key, holder, attempts: task.attempts });
200
+ const renew = () => this.registry.renew(key, { holder, ttlMs: this.ttlMs });
201
+ // A teammate-scoped messaging handle: post to a peer / broadcast, and read
202
+ // its own inbox (direct messages + unseen broadcasts).
203
+ const inbox = this.mailbox ? this.mailbox.drain(holder) : [];
204
+ const sendMessage = (to, body, subject = null) =>
205
+ this.mailbox
206
+ ? this.mailbox.send({ from: holder, to, subject, body })
207
+ : null;
208
+ const startedAt = this._now();
209
+ try {
210
+ const result = await this.runTask({
211
+ key,
212
+ task,
213
+ holder,
214
+ renew,
215
+ inbox,
216
+ sendMessage,
217
+ mailbox: this.mailbox,
218
+ budget: this.budget,
219
+ });
220
+ const done = this.registry.complete(key, { holder, result });
221
+ // Fold usage/cost into the team budget regardless — the task DID execute
222
+ // and consumed resources. `--exec` shell tasks carry no usage → only the
223
+ // task-count / wall-clock dimensions move.
224
+ if (this.budget) {
225
+ this.budget.record(
226
+ {
227
+ usage: result?.usage || null,
228
+ provider: result?.provider,
229
+ model: result?.model,
230
+ },
231
+ this._now(),
232
+ );
233
+ }
234
+ if (done.ok) {
235
+ this._setState(holder, "completed-task");
236
+ this._emit("task:completed", {
237
+ key,
238
+ holder,
239
+ ms: this._now() - startedAt,
240
+ });
241
+ } else {
242
+ // The registry REJECTED the completion — the lease expired mid-run (the
243
+ // task outran its TTL without renewing), so a peer may already own it.
244
+ // Reporting `task:completed` + bumping the completed counter here would
245
+ // be a phantom success (the registry has no record of it, and the task
246
+ // will be reclaimed and re-run). Surface the discard honestly instead so
247
+ // the event stream and per-teammate stats stay truthful.
248
+ this._emit("task:completion-discarded", {
249
+ key,
250
+ holder,
251
+ reason: done.reason,
252
+ ms: this._now() - startedAt,
253
+ });
254
+ }
255
+ } catch (err) {
256
+ // A failed task still consumed a task-count slot (and any wall-clock) — fold
257
+ // it so a doomed retry loop can't dodge the budget.
258
+ if (this.budget) this.budget.record({ usage: null }, this._now());
259
+ const outcome = this.registry.fail(key, {
260
+ holder,
261
+ error: err?.message || String(err),
262
+ });
263
+ this._setState(holder, "failed-task", {
264
+ error: err?.message || String(err),
265
+ });
266
+ this._emit("task:failed", {
267
+ key,
268
+ holder,
269
+ error: err?.message || String(err),
270
+ retry: outcome?.retry === true,
271
+ attempts: outcome?.attempts,
272
+ });
273
+ } finally {
274
+ this._inFlight--;
275
+ }
276
+ }
277
+
278
+ /** Yield to the event loop so peer completions land before re-checking. */
279
+ _tick() {
280
+ return new Promise((resolve) => setTimeout(resolve, 0));
281
+ }
282
+ }