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
@@ -5,6 +5,7 @@
5
5
  * cc permissions list [--json] merged ruleset + source file
6
6
  * cc permissions test <tool> <args...> dry-run: which rule decides?
7
7
  * cc permissions add <allow|ask|deny> <rule> append a rule to a settings file
8
+ * cc permissions allow|ask|deny <rule> convenience aliases for add
8
9
  * [--local | --user] (default target: project)
9
10
  *
10
11
  * The ruleset is loaded by settings-loader (user < project < local < env) and
@@ -23,7 +24,7 @@ const KIND_COLOR = {
23
24
  };
24
25
 
25
26
  const RUNTIME_ADVISORY =
26
- "advisory/not enforced: this command edits and dry-runs settings rules; the Agent runtime still has separate ApprovalGate/managed-policy wiring.";
27
+ "settings rules are enforced by the Agent Core when loaded into the active runtime; managed host policy and ApprovalGate still apply.";
27
28
 
28
29
  function printRuntimeAdvisory() {
29
30
  logger.log(chalk.yellow(RUNTIME_ADVISORY));
@@ -48,6 +49,48 @@ function buildArgs(tool, positional, rulesMod) {
48
49
  return {};
49
50
  }
50
51
 
52
+ async function persistPermissionRule(decision, rule, options, operation = "add") {
53
+ try {
54
+ const kind = String(decision || "").toLowerCase();
55
+ if (!["allow", "ask", "deny"].includes(kind)) {
56
+ logger.error(
57
+ chalk.red(`decision must be allow | ask | deny (got "${decision}")`),
58
+ );
59
+ process.exitCode = 1;
60
+ return;
61
+ }
62
+ const rulesMod = await import("../lib/permission-rules.cjs");
63
+ const mod = rulesMod.default || rulesMod;
64
+ if (!mod.parseRule(rule)) {
65
+ logger.error(
66
+ chalk.red(
67
+ `not a valid rule: "${rule}" (expected Tool or Tool(pattern), e.g. Bash(rm:*))`,
68
+ ),
69
+ );
70
+ process.exitCode = 1;
71
+ return;
72
+ }
73
+ const scope = options.user ? "user" : options.local ? "local" : "project";
74
+ const { addRule } = await import("../lib/settings-loader.cjs");
75
+ const { file, added } = addRule({
76
+ cwd: process.cwd(),
77
+ kind,
78
+ rule,
79
+ scope,
80
+ });
81
+ if (!added) {
82
+ logger.log(chalk.gray(`already present in ${file}: ${kind} ${rule}`));
83
+ return;
84
+ }
85
+ logger.log(
86
+ `${KIND_COLOR[kind].bold("✓ " + kind)} ${rule} ${chalk.gray("→ " + file)}`,
87
+ );
88
+ } catch (err) {
89
+ logger.error(chalk.red(`permissions ${operation} failed: ${err.message}`));
90
+ process.exitCode = 1;
91
+ }
92
+ }
93
+
51
94
  export function registerPermissionsCommand(program) {
52
95
  const cmd = program
53
96
  .command("permissions")
@@ -336,4 +379,17 @@ export function registerPermissionsCommand(program) {
336
379
  process.exitCode = 1;
337
380
  }
338
381
  });
382
+
383
+ // Explicit decision commands make the management surface easier to script
384
+ // and match the common `allow <rule>` / `deny <rule>` workflow.
385
+ for (const decision of ["allow", "ask", "deny"]) {
386
+ cmd
387
+ .command(`${decision} <rule>`)
388
+ .description(`Append an ${decision} permission rule`)
389
+ .option("--local", "Write to .claude/settings.local.json")
390
+ .option("--user", "Write to ~/.claude/settings.json")
391
+ .action(async (rule, options) => {
392
+ await persistPermissionRule(decision, rule, options, decision);
393
+ });
394
+ }
339
395
  }
@@ -1314,6 +1314,7 @@ export function registerPluginCommand(program) {
1314
1314
  const scope = options.scope === "project" ? "project" : "user";
1315
1315
  const current = optsMod.loadPluginOptionValues(name, scope, {
1316
1316
  cwd: process.cwd(),
1317
+ schema,
1317
1318
  });
1318
1319
  for (const pair of options.set) {
1319
1320
  const eq = pair.indexOf("=");
@@ -1326,6 +1327,7 @@ export function registerPluginCommand(program) {
1326
1327
  }
1327
1328
  optsMod.setPluginOptionValues(name, current, scope, {
1328
1329
  cwd: process.cwd(),
1330
+ schema,
1329
1331
  });
1330
1332
  logger.success(`Set option(s) for ${name} at ${scope} scope`);
1331
1333
  }
@@ -28,18 +28,22 @@
28
28
  * .chainlesschain/config.json `llm` exactly like `cc agent` / `cc ask`.
29
29
  */
30
30
 
31
- import { spawnSync } from "node:child_process";
32
31
  import fs from "node:fs";
33
32
  import path from "node:path";
34
33
  import chalk from "chalk";
35
34
  import { logger } from "../lib/logger.js";
36
35
  import { firstBalancedJson } from "../lib/json-schema-output.js";
36
+ import { executionBroker } from "../lib/process-execution-broker/index.js";
37
37
  import {
38
38
  dedupeFindings,
39
39
  buildReviewReport,
40
40
  findingKey,
41
41
  } from "../lib/review-pipeline.js";
42
42
 
43
+ export const _deps = {
44
+ spawnSync: (...args) => executionBroker.spawnSync(...args),
45
+ };
46
+
43
47
  /** Diffs larger than this are truncated before going to the model. */
44
48
  const MAX_DIFF_CHARS = 200_000;
45
49
  /** Per-untracked-file and total caps when inlining brand-new files. */
@@ -52,12 +56,16 @@ const VALID_EFFORTS = Object.freeze(["low", "medium", "high"]);
52
56
  * Run git with an argv array (no shell → no quoting hazards). UTF-8 in/out.
53
57
  * Returns trimmed stdout; throws with git's stderr on failure.
54
58
  */
55
- function gitCli(args, { cwd } = {}) {
56
- const res = spawnSync("git", args, {
59
+ export function gitCli(args, { cwd } = {}) {
60
+ const res = _deps.spawnSync("git", args, {
57
61
  cwd,
58
62
  encoding: "utf-8",
59
63
  windowsHide: true,
60
64
  maxBuffer: 256 * 1024 * 1024,
65
+ origin: "review:command-git",
66
+ policy: "allow",
67
+ scope: "review",
68
+ shell: false,
61
69
  });
62
70
  if (res.error) throw res.error;
63
71
  if (res.status !== 0) {
@@ -86,28 +94,28 @@ function isGitRepo(cwd, git = gitCli) {
86
94
  */
87
95
  export function resolveDiffArgs(opts = {}, stat = false) {
88
96
  const { staged, base, range, paths } = opts;
89
- let args;
97
+ const args = ["diff"];
98
+ if (stat) args.push("--stat");
90
99
  let scope;
91
100
  let label;
92
101
  if (range) {
93
- args = ["diff", range];
102
+ args.push("--end-of-options", range);
94
103
  scope = "range";
95
104
  label = `range ${range}`;
96
105
  } else if (base) {
97
106
  // three-dot: changes on HEAD since it diverged from <base> (PR-style).
98
- args = ["diff", `${base}...HEAD`];
107
+ args.push("--end-of-options", `${base}...HEAD`);
99
108
  scope = "base";
100
109
  label = `${base}...HEAD`;
101
110
  } else if (staged) {
102
- args = ["diff", "--cached"];
111
+ args.push("--cached");
103
112
  scope = "staged";
104
113
  label = "staged changes";
105
114
  } else {
106
- args = ["diff", "HEAD"];
115
+ args.push("HEAD");
107
116
  scope = "working";
108
117
  label = "working tree vs HEAD";
109
118
  }
110
- if (stat) args.push("--stat");
111
119
  const cleanPaths = Array.isArray(paths) ? paths.filter(Boolean) : [];
112
120
  if (cleanPaths.length) args.push("--", ...cleanPaths);
113
121
  return { args, scope, label };
@@ -361,13 +369,17 @@ function collectReviewDiff(scopeOpts, { cwd, git, includeUntracked }) {
361
369
  }
362
370
 
363
371
  /** Run `gh` with an argv array (no shell). UTF-8 in/out; throws on failure. */
364
- function ghCli(args, { cwd, input } = {}) {
365
- const res = spawnSync("gh", args, {
372
+ export function ghCli(args, { cwd, input } = {}) {
373
+ const res = _deps.spawnSync("gh", args, {
366
374
  cwd,
367
375
  input,
368
376
  encoding: "utf-8",
369
377
  windowsHide: true,
370
378
  maxBuffer: 64 * 1024 * 1024,
379
+ origin: "review:command-gh",
380
+ policy: "allow",
381
+ scope: "review",
382
+ shell: false,
371
383
  });
372
384
  if (res.error) throw res.error;
373
385
  if (res.status !== 0) {
@@ -13,11 +13,16 @@
13
13
  * agenda wakeup), exactly like `cc agenda run`.
14
14
  */
15
15
 
16
- import { spawn, execFile } from "node:child_process";
17
16
  import { readFileSync, existsSync } from "node:fs";
18
17
  import { fileURLToPath } from "node:url";
19
18
  import chalk from "chalk";
20
19
  import { logger } from "../lib/logger.js";
20
+ import { executionBroker } from "../lib/process-execution-broker/index.js";
21
+
22
+ export const _deps = {
23
+ spawn: (...args) => executionBroker.spawn(...args),
24
+ execFile: (...args) => executionBroker.execFile(...args),
25
+ };
21
26
 
22
27
  const BIN_PATH = fileURLToPath(
23
28
  new URL("../../bin/chainlesschain.js", import.meta.url),
@@ -29,12 +34,18 @@ async function loadStore() {
29
34
  }
30
35
 
31
36
  /** Production runner: `cc agent -p <prompt> --output-format json`. */
32
- function defaultRunAgent({ prompt }) {
37
+ export function defaultRunAgent({ prompt }) {
33
38
  return new Promise((resolve) => {
34
- const child = spawn(
39
+ const child = _deps.spawn(
35
40
  process.execPath,
36
- [BIN_PATH, "agent", "-p", prompt, "--output-format", "json"],
37
- { windowsHide: true },
41
+ [BIN_PATH, "agent", "--output-format", "json"],
42
+ {
43
+ windowsHide: true,
44
+ origin: "routine:agent",
45
+ policy: "allow",
46
+ scope: "routine",
47
+ shell: false,
48
+ },
38
49
  );
39
50
  let out = "";
40
51
  let err = "";
@@ -42,6 +53,10 @@ function defaultRunAgent({ prompt }) {
42
53
  child.stderr?.setEncoding("utf8");
43
54
  child.stdout?.on("data", (d) => (out += d));
44
55
  child.stderr?.on("data", (d) => (err += d));
56
+ if (child.stdin) {
57
+ child.stdin.on("error", () => {});
58
+ child.stdin.end(prompt);
59
+ }
45
60
  child.on("error", (error) =>
46
61
  resolve({ exitCode: -1, output: `spawn error: ${error.message}` }),
47
62
  );
@@ -70,12 +85,20 @@ function defaultRunAgent({ prompt }) {
70
85
  }
71
86
 
72
87
  /** Production github events fetch via gh CLI. */
73
- function defaultFetchEvents(repo) {
88
+ export function defaultFetchEvents(repo) {
74
89
  return new Promise((resolve) => {
75
- execFile(
90
+ _deps.execFile(
76
91
  "gh",
77
92
  ["api", `repos/${repo}/events`, "--paginate=false"],
78
- { encoding: "utf8", timeout: 8000, windowsHide: true },
93
+ {
94
+ encoding: "utf8",
95
+ timeout: 8000,
96
+ windowsHide: true,
97
+ origin: "routine:github-events",
98
+ policy: "allow",
99
+ scope: "routine",
100
+ shell: false,
101
+ },
79
102
  (err, stdout) => {
80
103
  if (err) return resolve([]);
81
104
  try {
@@ -61,6 +61,11 @@ import {
61
61
  listWorkflowSessions,
62
62
  readWorkflowSession,
63
63
  } from "../lib/workflow-state-reader.js";
64
+ import { executionBroker } from "../lib/process-execution-broker/index.js";
65
+
66
+ export const _deps = {
67
+ execFileSync: (...args) => executionBroker.execFileSync(...args),
68
+ };
64
69
 
65
70
  // DB sessions store `updated_at` as SQLite datetime('now') → "YYYY-MM-DD
66
71
  // HH:MM:SS" (UTC, space at index 10); JSONL sessions store toISOString() →
@@ -149,8 +154,7 @@ export function mapGhPrToSignals(gh = {}) {
149
154
  * mapped signals, or throws (caller degrades to a "pass --checks-file" hint).
150
155
  * 8s timeout, stderr suppressed — a missing / unauthenticated gh just fails.
151
156
  */
152
- async function fetchPrSignalsViaGh(target) {
153
- const { execFileSync } = await import("node:child_process");
157
+ export async function fetchPrSignalsViaGh(target) {
154
158
  const args = [
155
159
  "pr",
156
160
  "view",
@@ -159,10 +163,14 @@ async function fetchPrSignalsViaGh(target) {
159
163
  "number,state,headRefName,headRefOid,reviewDecision,statusCheckRollup",
160
164
  ];
161
165
  if (target.repo) args.push("--repo", String(target.repo));
162
- const out = execFileSync("gh", args, {
166
+ const out = _deps.execFileSync("gh", args, {
163
167
  encoding: "utf-8",
164
168
  timeout: 8000,
165
169
  stdio: ["ignore", "pipe", "ignore"],
170
+ origin: "session:pr-status",
171
+ policy: "allow",
172
+ scope: "pr",
173
+ shell: false,
166
174
  });
167
175
  return mapGhPrToSignals(JSON.parse(out));
168
176
  }
@@ -18,12 +18,16 @@
18
18
  import fs from "fs";
19
19
  import path from "path";
20
20
  import { fileURLToPath } from "url";
21
- import { spawn } from "child_process";
22
21
  import { TaskLeaseRegistry } from "../lib/agent-team/task-lease.js";
23
22
  import { TeamRunner } from "../lib/agent-team/team-runner.js";
24
23
  import { TeamWorktreeCoordinator } from "../lib/agent-team/team-worktree.js";
25
24
  import { TeamBudget } from "../lib/agent-team/team-budget.js";
26
25
  import { TeamMailbox } from "../lib/agent-team/team-mailbox.js";
26
+ import { executionBroker } from "../lib/process-execution-broker/index.js";
27
+
28
+ export const _deps = {
29
+ spawn: (...args) => executionBroker.spawn(...args),
30
+ };
27
31
 
28
32
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
29
33
  const BIN = path.resolve(__dirname, "..", "..", "bin", "chainlesschain.js");
@@ -94,17 +98,20 @@ function planWaves(reg) {
94
98
  }
95
99
 
96
100
  /** Real executor: run a task's shell `command`, success = exit 0. */
97
- function makeShellRunTask(logger) {
101
+ export function makeShellRunTask(logger) {
98
102
  return function runTask({ task }) {
99
103
  const command = task.metadata?.command || task?.command;
100
104
  if (!command) {
101
105
  throw new Error(`task "${task.key}" has no \`command\` to --exec`);
102
106
  }
103
107
  return new Promise((resolve, reject) => {
104
- const child = spawn(command, {
108
+ const child = _deps.spawn(command, [], {
105
109
  cwd: process.cwd(),
106
110
  shell: true,
107
111
  env: process.env,
112
+ origin: "team:shell",
113
+ policy: "allow",
114
+ scope: "team",
108
115
  });
109
116
  let err = "";
110
117
  child.stderr?.on("data", (d) => (err += d.toString("utf8")));
@@ -118,26 +125,32 @@ function makeShellRunTask(logger) {
118
125
  }
119
126
 
120
127
  /** Spawn a headless `cc agent -p` for one prompt in `cwd`; resolve on exit 0. */
121
- function spawnAgent(prompt, cwd, opts = {}) {
128
+ export function spawnAgent(prompt, cwd, opts = {}) {
122
129
  return new Promise((resolve, reject) => {
123
130
  const args = [
124
131
  BIN,
125
132
  "agent",
126
- "-p",
127
- prompt,
128
133
  "--permission-mode",
129
134
  opts.permissionMode || "acceptEdits",
130
135
  "--output-format",
131
136
  "text",
132
137
  ];
133
138
  if (opts.model) args.push("--model", opts.model);
134
- const child = spawn(process.execPath, args, {
139
+ const child = _deps.spawn(process.execPath, args, {
135
140
  cwd,
136
141
  env: { ...process.env, CLAUDECODE: "1" },
137
142
  windowsHide: true,
143
+ origin: "team:agent",
144
+ policy: "allow",
145
+ scope: "team",
146
+ shell: false,
138
147
  });
139
148
  let err = "";
140
149
  child.stderr?.on("data", (d) => (err += d.toString("utf8")));
150
+ if (child.stdin) {
151
+ child.stdin.on("error", () => {});
152
+ child.stdin.end(prompt);
153
+ }
141
154
  child.on("error", (e) => reject(new Error(e.message)));
142
155
  child.on("close", (code) =>
143
156
  code === 0
@@ -1,11 +1,58 @@
1
1
  import chalk from "chalk";
2
2
  import semver from "semver";
3
- import { execSync } from "node:child_process";
4
3
  import { checkForUpdates } from "../lib/version-checker.js";
5
4
  import { downloadRelease } from "../lib/downloader.js";
6
5
  import { VERSION } from "../constants.js";
7
6
  import { askConfirm } from "../lib/prompts.js";
8
7
  import logger from "../lib/logger.js";
8
+ import { executionBroker } from "../lib/process-execution-broker/index.js";
9
+ import { resolveNpmInvocation } from "../lib/npm-invocation.js";
10
+
11
+ export const _deps = {
12
+ platform: process.platform,
13
+ execPath: process.execPath,
14
+ cliEntryPath: process.argv[1] || null,
15
+ spawnSync: (...args) => executionBroker.spawnSync(...args),
16
+ };
17
+
18
+ export function updateProcessInvocations(
19
+ platform = _deps.platform,
20
+ execPath = _deps.execPath,
21
+ cliEntryPath = _deps.cliEntryPath,
22
+ ) {
23
+ return {
24
+ npm: resolveNpmInvocation({ platform, execPath }),
25
+ chainlesschain: cliEntryPath
26
+ ? { command: execPath, prefixArgs: [cliEntryPath] }
27
+ : {
28
+ command:
29
+ platform === "win32" ? "chainlesschain.cmd" : "chainlesschain",
30
+ prefixArgs: [],
31
+ },
32
+ };
33
+ }
34
+
35
+ function runUpdateProcess(command, args, origin) {
36
+ const result = _deps.spawnSync(command, args, {
37
+ encoding: "utf-8",
38
+ stdio: "pipe",
39
+ origin,
40
+ policy: "allow",
41
+ scope: "update",
42
+ shell: false,
43
+ });
44
+ if (result?.error) throw result.error;
45
+ if (result?.status != null && result.status !== 0) {
46
+ const error = new Error(
47
+ `Update process failed (exit ${result.status}): ${command}`,
48
+ );
49
+ error.status = result.status;
50
+ error.stdout = result.stdout;
51
+ error.stderr = result.stderr;
52
+ throw error;
53
+ }
54
+ return String(result?.stdout || "");
55
+ }
9
56
 
10
57
  /**
11
58
  * A version that is safe to interpolate into `npm install -g chainlesschain@<v>`.
@@ -19,7 +66,7 @@ export function isInstallableVersion(v) {
19
66
  return typeof v === "string" && semver.valid(v) !== null;
20
67
  }
21
68
 
22
- async function selfUpdateCli(targetVersion) {
69
+ export async function selfUpdateCli(targetVersion) {
23
70
  if (VERSION === targetVersion) {
24
71
  return true; // Already at the target version
25
72
  }
@@ -33,16 +80,24 @@ async function selfUpdateCli(targetVersion) {
33
80
 
34
81
  try {
35
82
  logger.info("Updating CLI package...");
36
- execSync(`npm install -g chainlesschain@${targetVersion}`, {
37
- encoding: "utf-8",
38
- stdio: "pipe",
39
- });
83
+ const invocations = updateProcessInvocations();
84
+ runUpdateProcess(
85
+ invocations.npm.command,
86
+ [
87
+ ...invocations.npm.prefixArgs,
88
+ "install",
89
+ "-g",
90
+ `chainlesschain@${targetVersion}`,
91
+ ],
92
+ "update:npm-install",
93
+ );
40
94
  // Verify the update actually took effect
41
95
  try {
42
- const newVersion = execSync("chainlesschain --version", {
43
- encoding: "utf-8",
44
- stdio: "pipe",
45
- }).trim();
96
+ const newVersion = runUpdateProcess(
97
+ invocations.chainlesschain.command,
98
+ [...invocations.chainlesschain.prefixArgs, "--version"],
99
+ "update:version-check",
100
+ ).trim();
46
101
  if (newVersion === targetVersion) {
47
102
  logger.success(`CLI updated to v${targetVersion}`);
48
103
  return true;
@@ -21,6 +21,7 @@ import EventEmitter from "events";
21
21
  import { randomUUID } from "crypto";
22
22
  import { createRequire } from "module";
23
23
  import { RingBuffer } from "./RingBuffer.js";
24
+ import { executionBroker } from "../../lib/process-execution-broker/index.js";
24
25
 
25
26
  const require = createRequire(import.meta.url);
26
27
 
@@ -66,6 +67,7 @@ export class PtyManager extends EventEmitter {
66
67
  this.config = { ...DEFAULT_CONFIG, ...(opts.config || {}) };
67
68
  this._deps = {
68
69
  loadNodePty: opts._deps?.loadNodePty || (() => require("node-pty")),
70
+ spawnPty: opts._deps?.spawnPty || null,
69
71
  now: opts._deps?.now || (() => Date.now()),
70
72
  };
71
73
  this._sessions = new Map();
@@ -110,12 +112,17 @@ export class PtyManager extends EventEmitter {
110
112
  req.env && typeof req.env === "object" && !Array.isArray(req.env)
111
113
  ? req.env
112
114
  : {};
113
- const proc = pty.spawn(cmd, [], {
115
+ const spawnPty =
116
+ this._deps.spawnPty || executionBroker.spawnPty.bind(executionBroker);
117
+ const proc = spawnPty(pty, cmd, [], {
114
118
  name: "xterm-256color",
115
119
  cols,
116
120
  rows,
117
121
  cwd,
118
122
  env: { ...process.env, ...extraEnv },
123
+ origin: "terminal:pty",
124
+ policy: "allow",
125
+ scope: "terminal",
119
126
  });
120
127
 
121
128
  const sessionId = randomUUID();
@@ -110,6 +110,9 @@ export function createWsMessageDispatcher(server) {
110
110
  "session-close": () => server._handleSessionClose(id, ws, message),
111
111
  "session-interrupt": () =>
112
112
  server._handleSessionInterrupt(id, ws, message),
113
+ "permission-rules-get": () => server._handlePermissionRulesGet(id, ws),
114
+ "permission-rules-set": () =>
115
+ server._handlePermissionRulesSet(id, ws, message),
113
116
  "slash-command": () => server._handleSlashCommand(id, ws, message),
114
117
  "session-answer": () => server._handleSessionAnswer(id, ws, message),
115
118
  "remote-session-create": () =>
@@ -96,6 +96,27 @@ async function ensureSessionHandler(server, ws, session) {
96
96
  envelopeBus: server.envelopeBus || null,
97
97
  });
98
98
 
99
+ // Route MCP elicitation through the authenticated WS question channel. The
100
+ // MCP client may be shared by the runtime, so this is deliberately only a
101
+ // transport hook; the MCP request/answer ids remain inside the pending
102
+ // interaction entry and unknown answers are ignored by the adapter.
103
+ if (
104
+ session.mcpClient &&
105
+ typeof session.mcpClient.setElicitationHandler === "function"
106
+ ) {
107
+ session.mcpClient.setElicitationHandler(
108
+ async (request) => {
109
+ const answer = await session.interaction.askElicitation(request);
110
+ if (answer == null) return { action: "cancel" };
111
+ if (typeof answer === "object") {
112
+ return { action: "accept", content: answer };
113
+ }
114
+ return { action: "accept", content: { value: answer } };
115
+ },
116
+ { sessionId: session.id, timeoutMs: 180000 },
117
+ );
118
+ }
119
+
99
120
  let handler;
100
121
  if (session.type === "chat") {
101
122
  const { WSChatHandler } = await import("../../lib/ws-chat-handler.js");
@@ -444,6 +465,11 @@ export function handleSessionList(server, id, ws) {
444
465
  export function handleSessionClose(server, id, ws, message) {
445
466
  const { sessionId } = message;
446
467
 
468
+ const closingSession = server.sessionManager?.getSession?.(sessionId);
469
+ if (closingSession?.mcpClient?.clearElicitationHandler) {
470
+ closingSession.mcpClient.clearElicitationHandler(sessionId);
471
+ }
472
+
447
473
  const handler = server.sessionHandlers.get(sessionId);
448
474
  if (handler && handler.destroy) {
449
475
  handler.destroy();