chainlesschain 0.162.175 → 0.162.176

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 (263) hide show
  1. package/package.json +10 -10
  2. package/src/assets/web-panel/assets/{AIOps-DherW0Rh.js → AIOps-BDLu5Elz.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-CDGfqt2Y.js → ActionButton-DH5us-CK.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-BYhkzdgD.js → Analytics-BZ0u8IFG.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-cEKk1cpb.js → AppLayout-Duu8xR14.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-_aXR3WWc.js → Artifacts-Br2YBbh_.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-CYAf-gY7.js → Audit-C3C6a482.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-D4Q20phR.js → BackgroundAgents-CzHvebcj.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-Cq0Tyk58.js → Backup-DZNHYDFd.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-CPj_CdAv.js → BaseInput-VRiC4fIx.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-BQ-Qq0es.js → Chat-Cm08WWAD.js} +4 -4
  12. package/src/assets/web-panel/assets/{ChatBubbleRenderer-Ci97vNTs.js → ChatBubbleRenderer-CGHYrugQ.js} +1 -1
  13. package/src/assets/web-panel/assets/{Checkbox-rke6l3yg.js → Checkbox-DtByk7d7.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-DiacrIPq.js → Codegen-CphXXOfD.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-Cx3BY-Up.js → Col-Hz86TnLR.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-DfmWiQy8.js → Community-HP03ltpD.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-DdQnpxy5.js → Compact-B_N1mqQz.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-lzliOH_r.js → Compliance-CVztRpi8.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-CYx4Un5k.js → Cowork-wUVOyZih.js} +4 -4
  20. package/src/assets/web-panel/assets/{Cron-BGDcPFlo.js → Cron-DW5TLJKw.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-0_X5g2ri.js → Crosschain-CrAFGhWH.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-C0PEf3Eu.js → DID-pA-oD8ke.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-DULQjQ58.js → Dashboard-CXrd5gAw.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-DGRHRbW6.js → Dropdown-EweJcsek.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-ChX8XPwB.js → EmailListRenderer-C9xVLPG4.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-Dyq6IBNu.js → FamilyGuardDashboard-CDcEEqlu.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-DH1NfAL2.js → Federation-DtZda9A_.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-BN1I_uNi.js → FormItemContext-CiYdcVz3.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-Dq_2UYpe.js → GenericCardRenderer-DA13uwA0.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-BAy1yvI2.js → Git-DzRhZD1O.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-Db6Q2iSy.js → Governance-D5RMgOSb.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-0ub6yHcr.js → Inference-BgrPfSNk.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-DtLetM36.js → KnowledgeGraph-DzjnD571.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-Bcoy7CUd.js → Logs-BhWzVDtN.js} +2 -2
  35. package/src/assets/web-panel/assets/{MarkdownRenderer-BfEMFAXf.js → MarkdownRenderer-BDape9cx.js} +1 -1
  36. package/src/assets/web-panel/assets/{Marketplace-tt2rzwRR.js → Marketplace-DJtL5GV7.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-BhOgX-MU.js → McpTools-CZcQygI7.js} +5 -5
  38. package/src/assets/web-panel/assets/{Memory-BJUxeWBL.js → Memory-DUWSDUUu.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-BwUY2G9w.js → MobileBridge-BTwq2WKY.js} +1 -1
  40. package/src/assets/web-panel/assets/MobileProjects-NZvvfDME.js +1 -0
  41. package/src/assets/web-panel/assets/{Mtc-B2WMboOm.js → Mtc-BiGugEQm.js} +5 -5
  42. package/src/assets/web-panel/assets/{MtcAudit-8pNEXO63.js → MtcAudit-DY7a6gUe.js} +2 -2
  43. package/src/assets/web-panel/assets/{Multisig-C1wm5a_1.js → Multisig-BQbDu_w7.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-C1QpKF7g.js → NLProgramming-CM2wXTLv.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-CiQUcxFu.js → Notes-DI6gGs1v.js} +4 -4
  46. package/src/assets/web-panel/assets/{NotificationSettings-BblDPJ_x.js → NotificationSettings-BsZOLWAB.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-DRjYcPtb.js → OrderTableRenderer-C48mu09U.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-Dp3VKB0X.js → Organization-Cds0_tXr.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-Czx161m9.js → Overflow-WunYMD87.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-ClFi6wOs.js → P2P-Bo6j4DDv.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-CRweW0lz.js → PdhVaultBrowser-Bh2XPD5f.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-BzcRoqTn.js → Permissions-EMvMMC8N.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-ChGTpNMd.js → PersonalDataHub-AX3ypUDV.js} +2 -2
  54. package/src/assets/web-panel/assets/{Pipeline-BMOOpKWA.js → Pipeline-BOx8HOgL.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-D0AZHObH.js → Privacy-tBeTVQVM.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-yYFlZ6Ja.js → ProjectInit-CVYg1W4M.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-DJNVuMQs.js → ProjectSettings-Dvt5I7y1.js} +2 -2
  58. package/src/assets/web-panel/assets/{Projects-Br0rBWH1.js → Projects-Cc7FC9-e.js} +1 -1
  59. package/src/assets/web-panel/assets/Providers-Ct8xqY-E.js +1 -0
  60. package/src/assets/web-panel/assets/{QrScannerModal-81NZOitV.js → QrScannerModal-Cni8Ooja.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-Dic2lCbJ.js → QuickAsk-BJVLKdxr.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-Dh9iwViE.js → Recommend-DPG8Rbbm.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-Bq9VYEFy.js → RemoteSession-DsdR7dCt.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-CxFZ-NbJ.js → Reputation-Csg1YM-b.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-BVSLcaX2.js → Row-D9DoFoEf.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-BbC-5DOH.js → RssFeed-BsvKrXMS.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-BfjZ1GCr.js → Search-DFUStfgQ.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-CVjhOV5r.js → Security-ILg1zxdK.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-D45u-Aqe.js → Services-Dd41PCaY.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-WkGoK4he.js → Skeleton-Bzo1cN80.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-D_jvQZcj.js → Skills-BDHh17P0.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-Bf4QTF3E.js → Sla-jl7UTiRY.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-DVpZdbMN.js → SpeechSettings-BePa-RF6.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-DEEojoMS.js → SyncSettings-DiqqDKGZ.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-DFwxpLIk.js → Tasks-DYQ_6lxj.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-Bzl-9wY5.js → Templates-JiDeI06L.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-0khxUOB8.js → Tenant-hhgI6zwS.js} +1 -1
  78. package/src/assets/web-panel/assets/Terminal-CjTZPa37.js +3 -0
  79. package/src/assets/web-panel/assets/{TimelineRenderer-B0Y4LONc.js → TimelineRenderer-B8uB5Llk.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-DEE07SFh.js → Tokens-C3b_6r2z.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-BM7xvA5z.js → Trigger-tIP7HKVe.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-Dv3ijvvZ.js → Trust-vjoc11vJ.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-B1-enmMt.js → UkeySign-DUPBnGuH.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-DYiIPByd.js → VideoEditing-CBvhUY5T.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-D-y374BQ.js → Wallet-DUaQ0uA5.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-HBDjcUhi.js → WebAuthn-DllSivjE.js} +5 -5
  87. package/src/assets/web-panel/assets/{WorkflowEditor-sKn4qTID.js → WorkflowEditor-xc8D3uO6.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-TVYhaBXj.js → chat-BVicU7oA.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-DMADxY9v.js → colors-DJzLmhLm.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-OftcHpO_.js → compact-item-BvYRfThE.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-DW1zVUSN.js → createContext-DGXxCBKR.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-BT46Y_QI.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-CaUathNp.js → hasIn-SBDJB1y4.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-CeCIYYG7.js → index-1SdDS6lR.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-DAfT3EMd.js → index-9gdI7uUW.js} +1 -1
  96. package/src/assets/web-panel/assets/index-B7nuIywP.js +1 -0
  97. package/src/assets/web-panel/assets/{index-sm1sGIxW.js → index-BJZf9DhV.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BBNg08cD.js → index-BO1itZaY.js} +3 -3
  99. package/src/assets/web-panel/assets/{index-CKNdnJRo.js → index-BTrBGBJs.js} +1 -1
  100. package/src/assets/web-panel/assets/{index--5UvwqH_.js → index-BYqz4Wrr.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-8YelceUU.js → index-Bf-ctERC.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-Lr0MO-GU.js → index-CKyEivf8.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DZdT8nio.js → index-CdGY9P8a.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-s-EnkUCn.js → index-Cf-O_g_8.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-pSVCBsG4.js → index-CloCgBUR.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-B-19mFhn.js → index-CoJAO1Lm.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DKjqFpYa.js → index-Crk5NTb0.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BJ1PjRY3.js → index-Cs2rmLFt.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-77kgkUgY.js → index-CtwqO5qo.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-D63QVAiJ.js → index-D7HimK0M.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-B52Ztt8Q.js → index-DCdRAgjy.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DHi634g9.js → index-DCqRS6da.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BFVbDpqg.js → index-DHVLJ8q0.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-BvRw4Fna.js → index-DKrvvWm4.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CZXYI5LU.js → index-DMarmfrv.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CM8W07sc.js → index-DRfiXB_p.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-iDmgT2Dg.js → index-Dm_77jgR.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-hXq7QRA_.js → index-DnjPdvR6.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BEzLLVYd.js → index-DonCnfMr.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-DYwwUKDg.js → index-DvUTDYXX.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DXcqvWBp.js → index-FxZzRyE1.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-Cmdv6Dev.js → index-MjC4G09d.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-C9JoaYSs.js → index-VMfwIH5G.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CK-p7Hji.js → index-YJkzy8ZF.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BupSWDcl.js → index-d5BVd-cL.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-Bg-7FpaL.js → index-e4fXH_WO.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CpDtN0dl.js → index-hxTODbM1.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-kdMl_0zL.js → index-lpaGoTH3.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-GUKz4Pv9.js → index-wcCL-miV.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DWVZ3T0t.js → index-xfluRkCT.js} +1 -1
  131. package/src/assets/web-panel/assets/index-ycwAfC-i.js +1 -0
  132. package/src/assets/web-panel/assets/{index-BSp1Ofvx.js → index-z1ZylsLq.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-DdcKTlQR.js → initDefaultProps-C1zO1KnY.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-CL-hTBQj.js → motion-CWLtEGmC.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-qYSAkxNG.js → move-DzD_C3Vm.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-ZwRSZtRP.js → mtc-parser-D880PYJl.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-Bld-8ftI.js → omit-CFR_z2ov.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-DGHs-a9Z.js → pickAttrs-srIhgrSC.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-DRQPMyI5.js → placementArrow-C1rXpibP.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-C5MJG_Yo.js → responsiveObserve-C30gRcSS.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-VZ-fpZCD.js → slide-CvtKiMfV.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-9ocfCyHk.js → statusUtils-DNHO7ITG.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-B6QAwAN5.js → styleChecker-Dt_Sl-g4.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-Bq1twor3.js → useFlexGapSupport-Cjev42Gh.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-DKZq96tz.js → useFs-Baxglj2V.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-D0RmRVXf.js → usePersonalDataHub-B4NkcLaP.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-D6kEj_tt.js → vnode-mIRkdT7o.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-2yfasoQf.js → zoom-HzI5DlH_.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/auth/npm-auth.js +30 -5
  151. package/src/commands/agenda.js +64 -2
  152. package/src/commands/agent.js +39 -1
  153. package/src/commands/config.js +70 -5
  154. package/src/commands/context.js +36 -2
  155. package/src/commands/hub.js +19 -1
  156. package/src/commands/memory.js +21 -6
  157. package/src/commands/permissions.js +57 -1
  158. package/src/commands/plugin.js +2 -0
  159. package/src/commands/review.js +23 -11
  160. package/src/commands/routine.js +31 -8
  161. package/src/commands/session.js +11 -3
  162. package/src/commands/team.js +20 -7
  163. package/src/commands/update.js +65 -10
  164. package/src/gateways/terminal/PtyManager.js +8 -1
  165. package/src/gateways/ws/message-dispatcher.js +3 -0
  166. package/src/gateways/ws/session-protocol.js +26 -0
  167. package/src/gateways/ws/ws-agent-handler.js +107 -69
  168. package/src/gateways/ws/ws-server.js +74 -2
  169. package/src/harness/jsonl-session-store.js +13 -6
  170. package/src/harness/mcp-client.js +200 -1
  171. package/src/lib/__tests__/personal-data-hub-aichat-wizard.test.js +15 -0
  172. package/src/lib/agent-coordinator.js +4 -0
  173. package/src/lib/agent-ipc-bus.js +32 -2
  174. package/src/lib/agent-sandbox.js +16 -2
  175. package/src/lib/agent-schedule-store.js +55 -0
  176. package/src/lib/agent-tool-admission.js +104 -0
  177. package/src/lib/api-key-helper.js +10 -2
  178. package/src/lib/async-hook-supervisor.cjs +12 -2
  179. package/src/lib/changelog.js +19 -11
  180. package/src/lib/channels/channel-manager.js +6 -0
  181. package/src/lib/channels/telegram-channel.js +11 -1
  182. package/src/lib/channels/webhook-channel.js +15 -3
  183. package/src/lib/checkpoint-store.js +10 -2
  184. package/src/lib/cloud/bundle.js +12 -2
  185. package/src/lib/code-review.js +32 -8
  186. package/src/lib/computer-use/control-backend.js +18 -3
  187. package/src/lib/context-breakdown.js +46 -0
  188. package/src/lib/context-source-ledger.js +43 -0
  189. package/src/lib/diff-review-follow-up.js +154 -0
  190. package/src/lib/downloader.js +17 -3
  191. package/src/lib/ensure-utf8.js +11 -3
  192. package/src/lib/event-runtime-producer.js +58 -0
  193. package/src/lib/event-runtime-store.js +354 -0
  194. package/src/lib/event-runtime-worker.js +109 -0
  195. package/src/lib/execution-backend.js +72 -21
  196. package/src/lib/git-integration.js +19 -4
  197. package/src/lib/hook-manager.js +6 -15
  198. package/src/lib/hook-runner.cjs +48 -3
  199. package/src/lib/hooks-v2-producers.js +15 -0
  200. package/src/lib/hooks-v2-runtime.js +70 -21
  201. package/src/lib/host-adb-bridge.js +111 -21
  202. package/src/lib/ide-context.js +128 -1
  203. package/src/lib/interaction-adapter.js +39 -0
  204. package/src/lib/json-schema-validate.js +190 -36
  205. package/src/lib/lan-pairing-preflight.js +13 -2
  206. package/src/lib/lsp/__tests__/lsp-server-registry.test.js +18 -0
  207. package/src/lib/lsp/lsp-client.js +18 -1
  208. package/src/lib/lsp/lsp-manager.js +4 -0
  209. package/src/lib/lsp/lsp-server-registry.js +11 -0
  210. package/src/lib/mcp-oauth.js +8 -2
  211. package/src/lib/npm-invocation.js +29 -0
  212. package/src/lib/packer/pkg-runner.js +13 -2
  213. package/src/lib/packer/precheck.js +33 -16
  214. package/src/lib/packer/web-panel-builder.js +16 -2
  215. package/src/lib/permission-rules.cjs +5 -1
  216. package/src/lib/personal-data-hub-aichat-wizard.js +22 -6
  217. package/src/lib/personal-data-hub-wiring.js +27 -3
  218. package/src/lib/plan-mode.js +204 -11
  219. package/src/lib/plugin-monitor-supervisor.js +39 -4
  220. package/src/lib/plugin-runtime/bin.js +45 -0
  221. package/src/lib/plugin-runtime/hooks.js +14 -1
  222. package/src/lib/plugin-runtime/install.js +2 -1
  223. package/src/lib/plugin-runtime/lsp.js +3 -0
  224. package/src/lib/plugin-runtime/mcp.js +8 -1
  225. package/src/lib/plugin-runtime/monitors.js +4 -0
  226. package/src/lib/plugin-runtime/plugin-options.js +74 -7
  227. package/src/lib/plugin-runtime/signature.js +45 -0
  228. package/src/lib/pr-create.js +21 -8
  229. package/src/lib/pr-link-ledger.js +15 -3
  230. package/src/lib/process-execution-broker/credential-agent.js +23 -3
  231. package/src/lib/process-execution-broker/index.js +315 -38
  232. package/src/lib/process-execution-broker/patch-child-process.js +2 -3
  233. package/src/lib/process-manager.js +18 -3
  234. package/src/lib/publish-workspace.js +14 -6
  235. package/src/lib/secret-store.js +159 -0
  236. package/src/lib/service-manager.js +64 -29
  237. package/src/lib/settings-hook-events.cjs +61 -1
  238. package/src/lib/settings-hooks.cjs +4 -0
  239. package/src/lib/side-effect-ledger.js +22 -0
  240. package/src/lib/sub-agent-context.js +5 -0
  241. package/src/lib/sub-agent-profiles.js +4 -0
  242. package/src/lib/turn-context.js +14 -8
  243. package/src/lib/unattended-action-policy.js +83 -0
  244. package/src/lib/update-notice.js +6 -2
  245. package/src/lib/with-file-lock.js +7 -0
  246. package/src/lib/ws-server.js +1 -0
  247. package/src/repl/agent-repl.js +32 -0
  248. package/src/repl/clipboard-copy.js +8 -2
  249. package/src/repl/pr-comments.js +30 -7
  250. package/src/runtime/agent-core.js +439 -87
  251. package/src/runtime/agent-runtime.js +1 -0
  252. package/src/runtime/coding-agent-contract-shared.cjs +52 -0
  253. package/src/runtime/coding-agent-policy.cjs +20 -0
  254. package/src/runtime/diagnostics.js +73 -8
  255. package/src/runtime/headless-runner.js +63 -0
  256. package/src/runtime/headless-stream.js +269 -17
  257. package/src/runtime/mcp-config.js +16 -1
  258. package/src/assets/web-panel/assets/MobileProjects-BLRfHhqi.js +0 -1
  259. package/src/assets/web-panel/assets/Providers-zZRhNtSu.js +0 -1
  260. package/src/assets/web-panel/assets/Terminal-DWGYhAYU.js +0 -3
  261. package/src/assets/web-panel/assets/devWarning-CLOk6rdE.js +0 -1
  262. package/src/assets/web-panel/assets/index-CSgUfMTM.js +0 -1
  263. package/src/assets/web-panel/assets/index-DliSZvAP.js +0 -1
@@ -13,6 +13,7 @@
13
13
 
14
14
  import { agentLoop, formatToolArgs } from "../../runtime/agent-core.js";
15
15
  import { classifyToolSideEffect } from "../../lib/side-effect-ledger.js";
16
+ import { DiffReviewFollowUpTracker } from "../../lib/diff-review-follow-up.js";
16
17
  import {
17
18
  loadSideEffectLedger,
18
19
  persistSideEffectLedger,
@@ -88,6 +89,8 @@ export class WSAgentHandler {
88
89
  const abortController = new AbortController();
89
90
  this._abortController = abortController;
90
91
  this._activeRequestId = requestId || null;
92
+ let sideEffectLedger = null;
93
+ let diffReviewFollowUps = null;
91
94
 
92
95
  try {
93
96
  const { session } = this;
@@ -159,88 +162,123 @@ export class WSAgentHandler {
159
162
  // persisted BEFORE it settles) and commit/fail on its result, so a bridge
160
163
  // worker killed mid-flight is surfaced for verification on resume (see
161
164
  // handleSessionResume) instead of being blindly replayed.
162
- const sideEffectLedger = loadSideEffectLedger(session.id);
165
+ sideEffectLedger = loadSideEffectLedger(session.id);
166
+ diffReviewFollowUps = new DiffReviewFollowUpTracker(sideEffectLedger);
163
167
  let currentSideEffectOpId = null;
164
168
 
165
- for await (const event of agentLoop(session.messages, loopOptions)) {
166
- switch (event.type) {
167
- case "slot-filling":
168
- this.interaction.emit("slot-filling", {
169
- requestId,
170
- slot: event.slot,
171
- question: event.question,
172
- });
173
- break;
174
-
175
- case "tool-executing":
176
- this.interaction.emit("tool-executing", {
177
- requestId,
178
- tool: event.tool,
179
- args: event.args,
180
- display: formatToolArgs(event.tool, event.args),
181
- });
182
- currentSideEffectOpId = null;
183
- {
184
- const se = classifyToolSideEffect(event.tool, event.args);
185
- if (se) {
186
- const opId = `ws:${session.id}:${Date.now()}:${this._sideEffectSeq++}`;
187
- currentSideEffectOpId = opId;
188
- sideEffectLedger
189
- .prepare(opId, {
190
- kind: se.kind,
191
- key: se.key,
192
- meta: {
193
- tool: event.tool,
194
- idempotencyKey: operationIdempotencyKey({
169
+ const runAgentTurn = async () => {
170
+ for await (const event of agentLoop(session.messages, loopOptions)) {
171
+ switch (event.type) {
172
+ case "slot-filling":
173
+ this.interaction.emit("slot-filling", {
174
+ requestId,
175
+ slot: event.slot,
176
+ question: event.question,
177
+ });
178
+ break;
179
+
180
+ case "tool-executing":
181
+ this.interaction.emit("tool-executing", {
182
+ requestId,
183
+ tool: event.tool,
184
+ args: event.args,
185
+ display: formatToolArgs(event.tool, event.args),
186
+ });
187
+ currentSideEffectOpId = null;
188
+ {
189
+ const se = classifyToolSideEffect(event.tool, event.args);
190
+ if (se) {
191
+ const opId = `ws:${session.id}:${Date.now()}:${this._sideEffectSeq++}`;
192
+ currentSideEffectOpId = opId;
193
+ sideEffectLedger
194
+ .prepare(opId, {
195
+ kind: se.kind,
196
+ key: se.key,
197
+ meta: {
195
198
  tool: event.tool,
196
- args: event.args,
197
- }),
198
- },
199
- })
200
- .start(opId);
199
+ idempotencyKey: operationIdempotencyKey({
200
+ tool: event.tool,
201
+ args: event.args,
202
+ }),
203
+ },
204
+ })
205
+ .start(opId);
206
+ persistSideEffectLedger(session.id, sideEffectLedger);
207
+ }
208
+ }
209
+ break;
210
+
211
+ case "tool-result":
212
+ this.interaction.emit("tool-result", {
213
+ requestId,
214
+ tool: event.tool,
215
+ result: event.result,
216
+ error: event.error,
217
+ });
218
+ if (currentSideEffectOpId) {
219
+ const err = event.error || event.result?.error || null;
220
+ if (event.result?._diffReviewAudit) {
221
+ diffReviewFollowUps.observe(
222
+ sideEffectLedger,
223
+ currentSideEffectOpId,
224
+ event.result._diffReviewAudit,
225
+ );
226
+ }
227
+ if (err)
228
+ sideEffectLedger.fail(
229
+ currentSideEffectOpId,
230
+ String(err).slice(0, 200),
231
+ );
232
+ else sideEffectLedger.commit(currentSideEffectOpId);
201
233
  persistSideEffectLedger(session.id, sideEffectLedger);
234
+ currentSideEffectOpId = null;
202
235
  }
203
- }
204
- break;
205
-
206
- case "tool-result":
207
- this.interaction.emit("tool-result", {
208
- requestId,
209
- tool: event.tool,
210
- result: event.result,
211
- error: event.error,
212
- });
213
- if (currentSideEffectOpId) {
214
- const err = event.error || event.result?.error || null;
215
- if (err)
216
- sideEffectLedger.fail(
217
- currentSideEffectOpId,
218
- String(err).slice(0, 200),
219
- );
220
- else sideEffectLedger.commit(currentSideEffectOpId);
221
- persistSideEffectLedger(session.id, sideEffectLedger);
222
- currentSideEffectOpId = null;
223
- }
224
- break;
225
-
226
- case "response-complete":
227
- if (event.content) {
228
- session.messages.push({
229
- role: "assistant",
236
+ break;
237
+
238
+ case "response-complete":
239
+ if (event.content) {
240
+ session.messages.push({
241
+ role: "assistant",
242
+ content: event.content,
243
+ });
244
+ }
245
+ this.interaction.emit("response-complete", {
246
+ requestId,
230
247
  content: event.content,
231
248
  });
232
- }
233
- this.interaction.emit("response-complete", {
234
- requestId,
235
- content: event.content,
236
- });
237
- break;
249
+ break;
250
+ }
238
251
  }
252
+ };
253
+
254
+ if (session.mcpClient?.withElicitationContext) {
255
+ await session.mcpClient.withElicitationContext(
256
+ session.id,
257
+ runAgentTurn,
258
+ );
259
+ } else {
260
+ await runAgentTurn();
261
+ }
262
+ if (
263
+ diffReviewFollowUps.complete(sideEffectLedger, {
264
+ status: "completed-without-reproposal",
265
+ }).length > 0
266
+ ) {
267
+ persistSideEffectLedger(session.id, sideEffectLedger);
239
268
  }
240
269
 
241
270
  // Update last activity
242
271
  session.lastActivity = new Date().toISOString();
243
272
  } catch (err) {
273
+ if (
274
+ sideEffectLedger &&
275
+ diffReviewFollowUps?.complete(sideEffectLedger, {
276
+ status: "interrupted",
277
+ reason: isAbortError(err) ? "aborted" : err.message,
278
+ }).length > 0
279
+ ) {
280
+ persistSideEffectLedger(this.session.id, sideEffectLedger);
281
+ }
244
282
  if (isAbortError(err) || abortController.signal.aborted) {
245
283
  return;
246
284
  }
@@ -11,7 +11,6 @@
11
11
  */
12
12
 
13
13
  import { EventEmitter } from "node:events";
14
- import { spawn } from "node:child_process";
15
14
  import { createHash, timingSafeEqual } from "node:crypto";
16
15
  import { fileURLToPath } from "node:url";
17
16
  import { dirname, join } from "node:path";
@@ -113,6 +112,11 @@ import {
113
112
  handleArtifactRemove,
114
113
  handleArtifactShow,
115
114
  } from "./artifact-protocol.js";
115
+ import { executionBroker } from "../../lib/process-execution-broker/index.js";
116
+
117
+ export const _deps = {
118
+ spawn: (...args) => executionBroker.spawn(...args),
119
+ };
116
120
 
117
121
  const __filename = fileURLToPath(import.meta.url);
118
122
  const __dirname = dirname(__filename);
@@ -216,6 +220,7 @@ export class ChainlessChainWSServer extends EventEmitter {
216
220
  * @param {string} [options.token] - If set, clients must authenticate first
217
221
  * @param {number} [options.maxConnections=10]
218
222
  * @param {number} [options.timeout=30000] - Command execution timeout (ms)
223
+ * @param {Function} [options.spawn] - Process seam for tests
219
224
  */
220
225
  constructor(options = {}) {
221
226
  super();
@@ -240,6 +245,7 @@ export class ChainlessChainWSServer extends EventEmitter {
240
245
  // grace window so it can't hold a maxConnections slot forever (see
241
246
  // AUTH_TIMEOUT_MS). `??` so an explicit 0 (disable) is honoured.
242
247
  this.authTimeoutMs = options.authTimeoutMs ?? AUTH_TIMEOUT_MS;
248
+ this._spawnProcess = options.spawn || _deps.spawn;
243
249
 
244
250
  /** Optional Phase-5 envelope bus for fan-out to hosted HTTP SSE. */
245
251
  this.envelopeBus = options.envelopeBus || null;
@@ -255,6 +261,7 @@ export class ChainlessChainWSServer extends EventEmitter {
255
261
 
256
262
  /** Session manager for stateful agent/chat sessions */
257
263
  this.sessionManager = options.sessionManager || null;
264
+ this.projectRoot = options.projectRoot || process.cwd();
258
265
 
259
266
  /** Session handlers: sessionId → WSAgentHandler | WSChatHandler */
260
267
  this.sessionHandlers = new Map();
@@ -530,6 +537,67 @@ export class ChainlessChainWSServer extends EventEmitter {
530
537
  return this._dispatcher.dispatch(clientId, ws, message);
531
538
  }
532
539
 
540
+ /** Read the same .claude settings rules used by the Agent Core. */
541
+ async _handlePermissionRulesGet(id, ws) {
542
+ try {
543
+ const { loadSettings } = await import("../../lib/settings-loader.cjs");
544
+ const loaded = loadSettings({ cwd: this.projectRoot });
545
+ this._send(ws, {
546
+ id,
547
+ type: "permission-rules",
548
+ rules: loaded.rules,
549
+ sources: loaded.sources,
550
+ files: loaded.files,
551
+ managed: loaded.managed || null,
552
+ });
553
+ } catch (error) {
554
+ this._send(ws, {
555
+ id,
556
+ type: "error",
557
+ code: "PERMISSION_RULES_READ_FAILED",
558
+ message: error.message,
559
+ });
560
+ }
561
+ }
562
+
563
+ /** Persist one rule through settings-loader; managed policy remains authoritative. */
564
+ async _handlePermissionRulesSet(id, ws, message) {
565
+ try {
566
+ const decision = String(message.decision || "").toLowerCase();
567
+ if (!["allow", "ask", "deny"].includes(decision)) {
568
+ throw new Error("decision must be allow, ask, or deny");
569
+ }
570
+ const rulesMod = await import("../../lib/permission-rules.cjs");
571
+ const mod = rulesMod.default || rulesMod;
572
+ if (!mod.parseRule(message.rule)) throw new Error("invalid permission rule");
573
+ const { addRule } = await import("../../lib/settings-loader.cjs");
574
+ const scope = ["project", "local", "user"].includes(message.scope)
575
+ ? message.scope
576
+ : "project";
577
+ const result = addRule({
578
+ cwd: this.projectRoot,
579
+ kind: decision,
580
+ rule: message.rule,
581
+ scope,
582
+ });
583
+ this._send(ws, {
584
+ id,
585
+ type: "permission-rule-updated",
586
+ ...result,
587
+ decision,
588
+ rule: message.rule,
589
+ scope,
590
+ });
591
+ } catch (error) {
592
+ this._send(ws, {
593
+ id,
594
+ type: "error",
595
+ code: "PERMISSION_RULES_WRITE_FAILED",
596
+ message: error.message,
597
+ });
598
+ }
599
+ }
600
+
533
601
  /**
534
602
  * Handle an orchestrate message — runs ChainlessChain orchestration with
535
603
  * real-time progress pushed back over this WebSocket connection.
@@ -854,7 +922,7 @@ export class ChainlessChainWSServer extends EventEmitter {
854
922
  return;
855
923
  }
856
924
 
857
- const child = spawn(process.execPath, [BIN_PATH, ...args], {
925
+ const child = this._spawnProcess(process.execPath, [BIN_PATH, ...args], {
858
926
  env: {
859
927
  ...process.env,
860
928
  FORCE_COLOR: "0",
@@ -870,6 +938,10 @@ export class ChainlessChainWSServer extends EventEmitter {
870
938
  },
871
939
  stdio: ["pipe", "pipe", "pipe"],
872
940
  windowsHide: true,
941
+ origin: "gateway:ws-command",
942
+ policy: "allow",
943
+ scope: "gateway",
944
+ shell: false,
873
945
  });
874
946
 
875
947
  this.processes.set(id, child);
@@ -20,6 +20,7 @@ import {
20
20
  verifyTranscriptText,
21
21
  TRANSCRIPT_CHAIN_STATUS,
22
22
  } from "./transcript-integrity.js";
23
+ import { withFileLock } from "../lib/with-file-lock.js";
23
24
 
24
25
  function getSessionsDir() {
25
26
  const dir = join(getHomeDir(), "sessions");
@@ -82,12 +83,18 @@ function _resolveChainTail(sessionId, filePath) {
82
83
 
83
84
  export function appendEvent(sessionId, type, data) {
84
85
  const filePath = sessionPath(sessionId);
85
- const prevHash = _resolveChainTail(sessionId, filePath);
86
- const core = { type, timestamp: Date.now(), data };
87
- const hash = computeEventHash(prevHash, core);
88
- const line = JSON.stringify({ ...core, prevHash, hash }) + "\n";
89
- appendFileSync(filePath, line, "utf-8");
90
- _chainTailCache.set(sessionId, hash);
86
+ withFileLock(
87
+ filePath,
88
+ () => {
89
+ const prevHash = _resolveChainTail(sessionId, filePath);
90
+ const core = { type, timestamp: Date.now(), data };
91
+ const hash = computeEventHash(prevHash, core);
92
+ const line = JSON.stringify({ ...core, prevHash, hash }) + "\n";
93
+ appendFileSync(filePath, line, "utf-8");
94
+ _chainTailCache.set(sessionId, hash);
95
+ },
96
+ { failIfUnavailable: true },
97
+ );
91
98
  }
92
99
 
93
100
  /**
@@ -9,9 +9,12 @@
9
9
  */
10
10
 
11
11
  import { spawn } from "child_process";
12
+ import { executionBroker } from "../lib/process-execution-broker/index.js";
13
+ import { AsyncLocalStorage } from "node:async_hooks";
12
14
  import { EventEmitter } from "events";
13
15
  import { pathToFileURL } from "url";
14
16
  import { safeJsonParse } from "../lib/safe-json.js";
17
+ import { EventRuntimeProducer } from "../lib/event-runtime-producer.js";
15
18
 
16
19
  /**
17
20
  * Injectable dependencies — overridable from tests.
@@ -166,6 +169,178 @@ export class MCPClient extends EventEmitter {
166
169
  options && Array.isArray(options.roots) && options.roots.length > 0
167
170
  ? options.roots.map(String)
168
171
  : null;
172
+ // MCP elicitation (server -> client `elicitation/create`). The handler is
173
+ // intentionally injected by the host (REPL, headless, or Desktop bridge)
174
+ // so the transport layer never reads stdin or invents an approval policy.
175
+ this._elicitationHandler =
176
+ typeof options.elicitationHandler === "function"
177
+ ? options.elicitationHandler
178
+ : null;
179
+ this._elicitationHandlers = new Map();
180
+ this._elicitationContext = new AsyncLocalStorage();
181
+ this._elicitationTimeoutMs =
182
+ Number(options.elicitationTimeoutMs) > 0
183
+ ? Number(options.elicitationTimeoutMs)
184
+ : 180000;
185
+ this._pendingElicitations = new Map();
186
+ this._runtimeProducer = options.eventRuntimeStore
187
+ ? new EventRuntimeProducer({ store: options.eventRuntimeStore, emitter: this })
188
+ : null;
189
+ }
190
+
191
+ /** Install or clear the host-side MCP elicitation resolver. */
192
+ setElicitationHandler(handler, options = {}) {
193
+ const sessionId = options.sessionId;
194
+ if (sessionId != null && sessionId !== "") {
195
+ const key = String(sessionId);
196
+ if (typeof handler === "function") this._elicitationHandlers.set(key, handler);
197
+ else this._elicitationHandlers.delete(key);
198
+ } else {
199
+ this._elicitationHandler =
200
+ typeof handler === "function" ? handler : null;
201
+ }
202
+ if (Number(options.timeoutMs) > 0) {
203
+ this._elicitationTimeoutMs = Number(options.timeoutMs);
204
+ }
205
+ }
206
+
207
+ /** Run an async agent turn with a session-scoped elicitation route. */
208
+ withElicitationContext(sessionId, fn) {
209
+ if (typeof fn !== "function") return Promise.resolve(undefined);
210
+ return this._elicitationContext.run(
211
+ sessionId == null ? null : String(sessionId),
212
+ fn,
213
+ );
214
+ }
215
+
216
+ /** Remove a session route when a WS session is closed. */
217
+ clearElicitationHandler(sessionId) {
218
+ if (sessionId == null || sessionId === "") return false;
219
+ return this._elicitationHandlers.delete(String(sessionId));
220
+ }
221
+
222
+ /** Resolve a pending server elicitation by its server/request id pair. */
223
+ respondElicitation(serverName, requestId, response) {
224
+ const key = this._elicitationKey(serverName, requestId);
225
+ const pending = this._pendingElicitations.get(key);
226
+ if (!pending) return false;
227
+ pending.resolve(this._normalizeElicitationResponse(response));
228
+ try {
229
+ this._runtimeProducer?.store.acknowledgeInbox(
230
+ `mcp-elicitation:${this._elicitationKey(serverName, requestId)}`,
231
+ { response: this._normalizeElicitationResponse(response) },
232
+ );
233
+ } catch {}
234
+ return true;
235
+ }
236
+
237
+ /** Cancel a pending server elicitation. */
238
+ cancelElicitation(serverName, requestId) {
239
+ return this.respondElicitation(serverName, requestId, {
240
+ action: "cancel",
241
+ });
242
+ }
243
+
244
+ _elicitationKey(serverName, requestId) {
245
+ return `${String(serverName)}:${String(requestId)}`;
246
+ }
247
+
248
+ _normalizeElicitationResponse(response) {
249
+ const action = String(response?.action || "decline").toLowerCase();
250
+ const safeAction = new Set(["accept", "decline", "cancel"]).has(action)
251
+ ? action
252
+ : "decline";
253
+ const normalized = { action: safeAction };
254
+ if (safeAction === "accept" && response?.content !== undefined) {
255
+ normalized.content = response.content;
256
+ }
257
+ return normalized;
258
+ }
259
+
260
+ async _resolveElicitation(serverName, requestId, params = {}) {
261
+ const key = this._elicitationKey(serverName, requestId);
262
+ try {
263
+ this._runtimeProducer?.publish(
264
+ { type: "mcp_elicitation", server: serverName, requestId, params },
265
+ { origin: "mcp", id: `mcp-elicitation:${key}` },
266
+ );
267
+ } catch (error) {
268
+ this.emit("elicitation-error", { server: serverName, requestId, error });
269
+ return { action: "cancel" };
270
+ }
271
+ const contextSessionId = this._elicitationContext.getStore();
272
+ const handler =
273
+ (contextSessionId && this._elicitationHandlers.get(contextSessionId)) ||
274
+ this._elicitationHandler;
275
+ if (handler) {
276
+ try {
277
+ const direct = await handler({
278
+ server: serverName,
279
+ requestId,
280
+ ...params,
281
+ });
282
+ if (direct !== undefined) {
283
+ const response = this._normalizeElicitationResponse(direct);
284
+ try {
285
+ this._runtimeProducer?.store.acknowledgeInbox(
286
+ `mcp-elicitation:${key}`,
287
+ { response },
288
+ );
289
+ } catch {}
290
+ return response;
291
+ }
292
+ } catch (error) {
293
+ this.emit("elicitation-error", {
294
+ server: serverName,
295
+ requestId,
296
+ error,
297
+ });
298
+ return { action: "cancel" };
299
+ }
300
+ }
301
+
302
+ // An event-driven host may answer later through respondElicitation().
303
+ // No handler/listener means fail closed with decline rather than leaving a
304
+ // server request hanging indefinitely.
305
+ if (this.listenerCount("elicitation-request") === 0) {
306
+ try {
307
+ this._runtimeProducer?.store.acknowledgeInbox(
308
+ `mcp-elicitation:${key}`,
309
+ { response: { action: "decline" } },
310
+ );
311
+ } catch {}
312
+ return { action: "decline" };
313
+ }
314
+ return new Promise((resolve) => {
315
+ const timeout = setTimeout(() => {
316
+ this._pendingElicitations.delete(key);
317
+ this.emit("elicitation-timeout", { server: serverName, requestId });
318
+ try {
319
+ this._runtimeProducer?.store.fail(
320
+ "inbox",
321
+ `mcp-elicitation:${key}`,
322
+ "elicitation timeout",
323
+ { retryDelayMs: 0, maxAttempts: 1 },
324
+ );
325
+ } catch {}
326
+ resolve({ action: "cancel" });
327
+ }, this._elicitationTimeoutMs);
328
+ timeout.unref?.();
329
+ this._pendingElicitations.set(key, {
330
+ resolve: (response) => {
331
+ clearTimeout(timeout);
332
+ this._pendingElicitations.delete(key);
333
+ resolve(this._normalizeElicitationResponse(response));
334
+ },
335
+ });
336
+ this.emit("elicitation-request", {
337
+ server: serverName,
338
+ requestId,
339
+ ...params,
340
+ respond: (response) => this.respondElicitation(serverName, requestId, response),
341
+ cancel: () => this.cancelElicitation(serverName, requestId),
342
+ });
343
+ });
169
344
  }
170
345
 
171
346
  /**
@@ -311,7 +486,10 @@ export class MCPClient extends EventEmitter {
311
486
  `stdio transport requires a command (server "${name}")`,
312
487
  );
313
488
  }
314
- const proc = _deps.spawn(config.command, config.args || [], {
489
+ const spawnFn = String(config.origin || "").startsWith("plugin:")
490
+ ? executionBroker.spawn.bind(executionBroker)
491
+ : _deps.spawn;
492
+ const proc = spawnFn(config.command, config.args || [], {
315
493
  stdio: ["pipe", "pipe", "pipe"],
316
494
  // process.env < agent identity (CLAUDECODE / session id) < the
317
495
  // server's own config.env, so an explicit per-server override wins.
@@ -320,6 +498,15 @@ export class MCPClient extends EventEmitter {
320
498
  ...this._agentIdentityEnv(),
321
499
  ...(config.env || {}),
322
500
  },
501
+ ...(config.origin
502
+ ? {
503
+ origin: config.origin,
504
+ policy: config.policy || "allow",
505
+ pluginId: config.pluginId,
506
+ pluginVersion: config.pluginVersion,
507
+ pluginSource: config.pluginSource,
508
+ }
509
+ : {}),
323
510
  });
324
511
 
325
512
  entry.process = proc;
@@ -510,6 +697,12 @@ export class MCPClient extends EventEmitter {
510
697
  const entry = this.servers.get(name);
511
698
  if (!entry) return false;
512
699
 
700
+ for (const [key, pending] of this._pendingElicitations) {
701
+ if (key.startsWith(`${String(name)}:`)) {
702
+ pending.resolve({ action: "cancel" });
703
+ }
704
+ }
705
+
513
706
  if (entry.process) {
514
707
  entry.process.kill();
515
708
  }
@@ -1125,6 +1318,12 @@ export class MCPClient extends EventEmitter {
1125
1318
  this._sendResponse(serverName, id, {});
1126
1319
  return;
1127
1320
  }
1321
+ if (method === "elicitation/create") {
1322
+ this._resolveElicitation(serverName, id, msg.params || {})
1323
+ .then((response) => this._sendResponse(serverName, id, response))
1324
+ .catch(() => this._sendResponse(serverName, id, { action: "cancel" }));
1325
+ return;
1326
+ }
1128
1327
  this._sendResponse(serverName, id, undefined, {
1129
1328
  code: -32601,
1130
1329
  message: `method not found: ${method}`,
@@ -91,6 +91,21 @@ describe("createVendorAdapterBridge (cli)", () => {
91
91
  expect(r.userId).toBe("userToken");
92
92
  });
93
93
 
94
+ it("attaches a validated session to the registry runtime adapter", async () => {
95
+ const runtimeAdapter = { setSession: vi.fn() };
96
+ const bridge = createVendorAdapterBridge({
97
+ specs: [fakeSpec("deepseek", async () => ({ ok: true }))],
98
+ runtimeAdapter,
99
+ _httpClientFactory: () => ({}),
100
+ });
101
+
102
+ await bridge.registerVendor("deepseek", { userToken: "abc" });
103
+
104
+ expect(runtimeAdapter.setSession).toHaveBeenCalledOnce();
105
+ expect(runtimeAdapter.setSession.mock.calls[0][0]).toBe("deepseek");
106
+ expect(runtimeAdapter.setSession.mock.calls[0][1].get("userToken")).toBe("abc");
107
+ });
108
+
94
109
  it("UNKNOWN_VENDOR for unrecognized", async () => {
95
110
  const bridge = createVendorAdapterBridge({
96
111
  specs: [fakeSpec("deepseek", async () => ({ ok: true }))],
@@ -281,6 +281,8 @@ export const ROLE_TOOL_WHITELIST = {
281
281
  "read_file",
282
282
  "write_file",
283
283
  "edit_file",
284
+ "delete_file",
285
+ "move_file",
284
286
  "run_shell",
285
287
  "search_files",
286
288
  "list_dir",
@@ -297,6 +299,8 @@ export const ROLE_TOOL_WHITELIST = {
297
299
  "read_file",
298
300
  "write_file",
299
301
  "edit_file",
302
+ "delete_file",
303
+ "move_file",
300
304
  "run_shell",
301
305
  "search_files",
302
306
  "list_dir",