chainlesschain 0.162.179 → 0.162.181

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 (251) hide show
  1. package/package.json +6 -3
  2. package/src/assets/web-panel/.build-hash +1 -1
  3. package/src/assets/web-panel/assets/{AIOps-BF13YdB-.js → AIOps-cq0dwbnf.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-B9y67AjF.js → ActionButton-CvcgGl3w.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-FcdDHoSC.js → Analytics-hM2-jFqg.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-CRm_zwSp.js → AppLayout-B9_Gsd_g.js} +5 -5
  7. package/src/assets/web-panel/assets/{Artifacts-Cbo7-usf.js → Artifacts-B7bu52Og.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-vMaLpkHC.js → Audit-DThfDgqB.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-FiUY692t.js → BackgroundAgents-DjlFiD4v.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-BK80j_GQ.js → Backup-CK9xJKnG.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-ChNMuYR1.js → BaseInput-DEiSU8K8.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-928UREpm.js → Chat-CpT96czj.js} +5 -5
  13. package/src/assets/web-panel/assets/ChatBubbleRenderer-BKPPNmZI.js +1 -0
  14. package/src/assets/web-panel/assets/{Checkbox-dFW-zDbe.js → Checkbox-C1GfDnO0.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-BCcNJUj2.js → Codegen-3DAKgiLx.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-DcEkLv70.js → Col-74cOwZU1.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-DihBRRqg.js → Community-tn9Kkz9j.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-DGYxwWET.js → Compact-BcoXH7m4.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-OnYe1vS4.js → Compliance-DIPGUBgi.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-CmWB54c2.js → Cowork-doD5_91c.js} +2 -2
  21. package/src/assets/web-panel/assets/{Cron-BrANb2uw.js → Cron-C-IDvubz.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-2HgWzSxg.js → Crosschain-CdcCoBdj.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-DdDwNI6K.js → DID-DdH5aMMA.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-D6PnE78-.js → Dashboard-DHLA4mm0.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-ClzvSN4O.js → Dropdown-dEeCt7Md.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-BUk9B727.js → EmailListRenderer-BMaecFv9.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-C8hi3v7i.js → FamilyGuardDashboard-DUaUukTN.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-B5SP8xkg.js → Federation-CMBE0_rp.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-DWzJ8AU5.js → FormItemContext-PG-JDbXq.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-3E3Q3rjG.js → GenericCardRenderer-Bcb0p88m.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-z8IdCMId.js → Git-Bgv15myB.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-CgqCF9lX.js → Governance-DB8YTArI.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-zgS-AuH9.js → Inference-BQMwCWaS.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-BdbgmESJ.js → KnowledgeGraph-B1_ZziiB.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-BHpknnjy.js → Logs-DovEEnt_.js} +2 -2
  36. package/src/assets/web-panel/assets/MarkdownRenderer-D201OL4T.js +1 -0
  37. package/src/assets/web-panel/assets/{Marketplace-Di9sAR7j.js → Marketplace-BlCXSpyB.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-DtnR9Z_A.js → McpTools-CsCR09Wj.js} +5 -5
  39. package/src/assets/web-panel/assets/{Memory-BaX9uuXD.js → Memory-CBVRLKno.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge-xelyKWTY.js → MobileBridge-C9OIafgA.js} +1 -1
  41. package/src/assets/web-panel/assets/{MobileProjects-BiFTOGBN.js → MobileProjects-D_zoJ8Xs.js} +1 -1
  42. package/src/assets/web-panel/assets/{Mtc-bV3OzTiO.js → Mtc-vE-HdvLj.js} +4 -4
  43. package/src/assets/web-panel/assets/{MtcAudit-BkwvFTdZ.js → MtcAudit-CPLaekCd.js} +2 -2
  44. package/src/assets/web-panel/assets/{Multisig-_6HQQ-oC.js → Multisig-C_UP9C2o.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-BBYhmWQZ.js → NLProgramming-2nODJcU1.js} +1 -1
  46. package/src/assets/web-panel/assets/{Notes-Cq-6dQnU.js → Notes-BhE-SJGu.js} +3 -3
  47. package/src/assets/web-panel/assets/{NotificationSettings-ILZ9zkX6.js → NotificationSettings-D21q7BNU.js} +1 -1
  48. package/src/assets/web-panel/assets/{OrderTableRenderer-DgmTBEvk.js → OrderTableRenderer-0b62GYOD.js} +1 -1
  49. package/src/assets/web-panel/assets/{Organization-CkLnWwCk.js → Organization-CEqmw_sb.js} +4 -4
  50. package/src/assets/web-panel/assets/{Overflow-CWVHZbhf.js → Overflow-MW-gMDO_.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-BXbqETkr.js → P2P-CY0hjI_G.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser--0JR-0ex.js → PdhVaultBrowser-BbWh7Man.js} +3 -3
  53. package/src/assets/web-panel/assets/{Permissions-Cz9_tfSy.js → Permissions-ChqEA_4Q.js} +4 -4
  54. package/src/assets/web-panel/assets/{PersonalDataHub-Dq7OWYtx.js → PersonalDataHub-B3YrbYfD.js} +5 -5
  55. package/src/assets/web-panel/assets/{Pipeline-DHPUNcc-.js → Pipeline-B8WBhhlW.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-CEAbrDkS.js → Privacy-Cmb0PXNx.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-CJYfclXE.js → ProjectInit-hF6zW3Nz.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-oCTgPCgp.js → ProjectSettings-BFSVfpW0.js} +2 -2
  59. package/src/assets/web-panel/assets/Projects-DAWkVFkc.js +1 -0
  60. package/src/assets/web-panel/assets/{Providers-BLTZtzTG.js → Providers-B8yux8Dx.js} +1 -1
  61. package/src/assets/web-panel/assets/{QrScannerModal-C0b0TQB3.js → QrScannerModal-N76cQluO.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-tOl6N_gM.js → QuickAsk-ClvZ0KYR.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-DPzKr8yr.js → Recommend-B-GfgBpT.js} +1 -1
  64. package/src/assets/web-panel/assets/RemoteSession-mlglCdQi.js +5 -0
  65. package/src/assets/web-panel/assets/{Reputation-Cji1Vl79.js → Reputation-DJIZzQeG.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-D-NERWf2.js → Row-COzxu_bb.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-DzlgmAlB.js → RssFeed-CoYsJQuE.js} +3 -3
  68. package/src/assets/web-panel/assets/{Search-Cs0SWSa4.js → Search-DC77Mq9S.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-DL7EzcUO.js → Security-Loy2EdMO.js} +4 -4
  70. package/src/assets/web-panel/assets/{Services-CT-PzgTd.js → Services-GUD07Eu0.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-tByJWdJg.js → Skeleton-DWzkptYU.js} +1 -1
  72. package/src/assets/web-panel/assets/{Skills-Dnr_6TTl.js → Skills-CEDn1r-Z.js} +1 -1
  73. package/src/assets/web-panel/assets/{Sla-4O-yq0LY.js → Sla-ub_k4pXh.js} +1 -1
  74. package/src/assets/web-panel/assets/{SpeechSettings-BYBVg1oR.js → SpeechSettings-D7HLX9CA.js} +1 -1
  75. package/src/assets/web-panel/assets/{SyncSettings-CpOYPbE5.js → SyncSettings-DbwOvl6m.js} +2 -2
  76. package/src/assets/web-panel/assets/{Tasks-CGVhOVh6.js → Tasks-CBQzoAu5.js} +1 -1
  77. package/src/assets/web-panel/assets/{Templates-BuHFxR4X.js → Templates-BNVeIhud.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant-DxDxHzgf.js → Tenant-PS9AzhXU.js} +1 -1
  79. package/src/assets/web-panel/assets/{Terminal-B9g_nISg.js → Terminal-Cgb4eLB_.js} +2 -2
  80. package/src/assets/web-panel/assets/{TimelineRenderer-DlrBC_4A.js → TimelineRenderer-CrmXMOkg.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-DvBlYZ6i.js → Tokens-DD-VDHw1.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-Dg8G9bhF.js → Trigger-BsoN_n-n.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-COICx4E-.js → Trust-n8LmN4ZV.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-B4pOBv7T.js → UkeySign-C9_7MImA.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-Qt4NMA8Q.js → VideoEditing-DyBteNgn.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-X1EkQc2Z.js → Wallet-BS5ixeXI.js} +4 -4
  87. package/src/assets/web-panel/assets/{WebAuthn-CyeEFBE5.js → WebAuthn-spc4UImU.js} +3 -3
  88. package/src/assets/web-panel/assets/{WorkflowEditor-nwzbMiVQ.js → WorkflowEditor-D7iVvaBO.js} +1 -1
  89. package/src/assets/web-panel/assets/chat-6CmBkHrL.js +1 -0
  90. package/src/assets/web-panel/assets/{colors-5Isz5lhJ.js → colors-BGoCLkxI.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-DsFQS3Oy.js → compact-item-fYZBetMO.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-OcEXp2uz.js → createContext-BeM-1UVj.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-BzPwHnw8.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-CZvC4p09.js → hasIn-CE7ZuEnV.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-BF1sab0Q.js → index--lap6cf7.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-C7yeL3rf.js → index-ATcSr_2O.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-VkFXA9N-.js → index-B2U-ObMq.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DSmGGg5h.js → index-B3CDgvNW.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-jrNIrpq4.js → index-B4wiTEOM.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-B8ibl7bc.js → index-B8BsdNV_.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DOLozRk8.js → index-BEVm0lCS.js} +10 -10
  102. package/src/assets/web-panel/assets/{index-BPgc_bdR.js → index-BNZDILcO.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BTZZzlMO.js → index-BU_2qiDk.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-Vubi6Tf5.js → index-BV551878.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-nXrnztXp.js → index-BfPL-m46.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CN8lPVpQ.js → index-BowH1eLQ.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BgE2BZl2.js → index-BsMfoaeo.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-Cd5b2JHB.js → index-BunaQCa0.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-CQlGw0nQ.js → index-C0v6YKKO.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Do6FJK32.js → index-C4SJVjs4.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Bqvo1f9T.js → index-C9Y3k0HI.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-LUdgPZg9.js → index-CIpVrf5P.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BpD2O7_p.js → index-CRLjEP1H.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-r_9NG6P7.js → index-CRnUE8Cb.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-FIgMAfBh.js → index-Cip8emOQ.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-RsQ1lFDV.js → index-CpIGIB85.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DGJupV0S.js → index-D1r9tT3J.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BpglwPWl.js → index-DT3zPSVX.js} +1 -1
  119. package/src/assets/web-panel/assets/index-DacrAdc-.js +1 -0
  120. package/src/assets/web-panel/assets/{index-CG3B2wCF.js → index-De0quFDw.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CxA2PDK1.js → index-DoXk5KJ8.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DaGKOVvQ.js → index-DsvfrESp.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-C7CtJYXq.js → index-Dw1PyYPm.js} +1 -1
  124. package/src/assets/web-panel/assets/index-EHzNJozo.js +1 -0
  125. package/src/assets/web-panel/assets/{index-Bu9NXvIa.js → index-MtOuq2i6.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BsZkTaa3.js → index-Puq6Luf1.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CPE4zHXF.js → index-QIpnpZgz.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Bsb-iylv.js → index-RMZ8a7Yt.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DMtGRQqw.js → index-WUrJ6S1j.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-C3lWvhk4.js → index-YjcumOZ4.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-CmVbCGx_.js → index-lJBjB1QX.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-A5SHQW_M.js → index-ukg99D1V.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-CFJgt6qM.js → index-zb7rVOhV.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-Cdgep9YT.js → initDefaultProps-CYHMs1ag.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-7yn1ACEm.js → motion-DDB2Ffk5.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-D8o133Xc.js → move-Bg3cD-dX.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-CClHIG9V.js → mtc-parser-B5nedjTS.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-CLnrPE2d.js → omit-BHyuUILu.js} +1 -1
  139. package/src/assets/web-panel/assets/{pickAttrs-1CTWoZWl.js → pickAttrs-C9YQnEN9.js} +1 -1
  140. package/src/assets/web-panel/assets/{placementArrow-xNNtS4Sp.js → placementArrow-DBUFYUe7.js} +1 -1
  141. package/src/assets/web-panel/assets/{responsiveObserve-ypzAofs7.js → responsiveObserve-nBs2Obnk.js} +1 -1
  142. package/src/assets/web-panel/assets/{slide-QsrY9UwD.js → slide-DkCEaXNU.js} +1 -1
  143. package/src/assets/web-panel/assets/{statusUtils-DSdThzOB.js → statusUtils-aqE1Wi6U.js} +1 -1
  144. package/src/assets/web-panel/assets/{styleChecker-B_kKM8Ob.js → styleChecker-CN5bhfHB.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFlexGapSupport-CcdTBNV9.js → useFlexGapSupport-B_oX_kvJ.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFs-BuAH2XFU.js → useFs-rCuXHeme.js} +1 -1
  147. package/src/assets/web-panel/assets/{usePersonalDataHub-B3zWiG4A.js → usePersonalDataHub-DZR9Abyd.js} +1 -1
  148. package/src/assets/web-panel/assets/{vnode-B45Rc-CQ.js → vnode-ConCYQlX.js} +1 -1
  149. package/src/assets/web-panel/assets/{zoom-DaYZDU5f.js → zoom-CUdDxG5M.js} +1 -1
  150. package/src/assets/web-panel/index.html +1 -1
  151. package/src/commands/agent.js +4 -1
  152. package/src/commands/background-session.js +2 -1
  153. package/src/commands/context.js +69 -2
  154. package/src/commands/hub.js +30 -24
  155. package/src/data/changelog.json +27 -1
  156. package/src/gateways/ws/background-agent-protocol.js +38 -0
  157. package/src/gateways/ws/message-dispatcher.js +1 -0
  158. package/src/gateways/ws/remote-session-protocol.js +65 -6
  159. package/src/gateways/ws/ws-server.js +8 -1
  160. package/src/harness/feature-flags.js +15 -8
  161. package/src/harness/mcp-client.js +618 -43
  162. package/src/lazy-dispatch.js +30 -1
  163. package/src/lib/agent-authority.js +22 -0
  164. package/src/lib/agent-core.js +2 -0
  165. package/src/lib/agent-sandbox.js +161 -0
  166. package/src/lib/agent-team/team-runner.js +22 -0
  167. package/src/lib/artifact-store.js +35 -0
  168. package/src/lib/async-hook-supervisor.cjs +13 -2
  169. package/src/lib/audit-mtc.js +3 -2
  170. package/src/lib/background-agent-supervisor.js +104 -3
  171. package/src/lib/background-interaction-journal.js +407 -0
  172. package/src/lib/background-interaction-resolver.js +23 -34
  173. package/src/lib/background-session-transport.js +12 -2
  174. package/src/lib/capability-manifest.js +41 -3
  175. package/src/lib/capability-negotiation.js +1 -1
  176. package/src/lib/channels/channel-manager.js +33 -0
  177. package/src/lib/channels/telegram-channel.js +23 -5
  178. package/src/lib/channels/webhook-channel.js +38 -15
  179. package/src/lib/chrome-connector.js +169 -23
  180. package/src/lib/config-manager.js +23 -9
  181. package/src/lib/context-breakdown.js +31 -0
  182. package/src/lib/cowork-cron.js +274 -32
  183. package/src/lib/cross-chain-mtc.js +3 -2
  184. package/src/lib/durable-security-store.js +124 -0
  185. package/src/lib/event-runtime-host.js +67 -6
  186. package/src/lib/event-runtime-store.js +163 -0
  187. package/src/lib/goal-store.js +32 -12
  188. package/src/lib/headless-manifest.js +2 -1
  189. package/src/lib/hook-environment.cjs +58 -0
  190. package/src/lib/hook-manager.js +12 -5
  191. package/src/lib/hook-runner.cjs +122 -28
  192. package/src/lib/hook-runner.js +1 -0
  193. package/src/lib/hooks-v2-producers.js +36 -0
  194. package/src/lib/hooks-v2-runtime.js +329 -52
  195. package/src/lib/interaction-adapter.js +60 -19
  196. package/src/lib/interaction-binding.js +64 -0
  197. package/src/lib/json-schema-output.js +439 -14
  198. package/src/lib/json-schema-validate.js +514 -883
  199. package/src/lib/lan-pairing-tokens.js +115 -57
  200. package/src/lib/lsp/__tests__/lsp-client.test.js +32 -0
  201. package/src/lib/lsp/__tests__/lsp-manager.test.js +25 -0
  202. package/src/lib/lsp/lsp-client.js +4 -0
  203. package/src/lib/lsp/lsp-manager.js +3 -0
  204. package/src/lib/lsp/lsp-server-registry.js +18 -0
  205. package/src/lib/mcp-client.js +1 -0
  206. package/src/lib/mcp-oauth.js +35 -21
  207. package/src/lib/packer/pkg-config-generator.js +1 -0
  208. package/src/lib/permission-decision.js +99 -0
  209. package/src/lib/plugin-monitor-supervisor.js +3 -0
  210. package/src/lib/plugin-runtime/capabilities.js +50 -0
  211. package/src/lib/plugin-runtime/capability-consent.js +42 -35
  212. package/src/lib/plugin-runtime/hooks.js +36 -9
  213. package/src/lib/plugin-runtime/install.js +23 -7
  214. package/src/lib/plugin-runtime/lsp.js +4 -0
  215. package/src/lib/plugin-runtime/manifest.js +50 -2
  216. package/src/lib/plugin-runtime/mcp.js +30 -5
  217. package/src/lib/plugin-runtime/monitors.js +11 -0
  218. package/src/lib/plugin-runtime/plugin-options.js +94 -38
  219. package/src/lib/plugin-runtime/policy.js +29 -2
  220. package/src/lib/plugin-runtime/sandbox-policy.js +84 -0
  221. package/src/lib/plugin-runtime/scopes.js +7 -3
  222. package/src/lib/plugin-runtime/trust.js +36 -31
  223. package/src/lib/process-execution-broker/credential-agent.js +114 -16
  224. package/src/lib/process-execution-broker/credential-transport-worker.js +312 -0
  225. package/src/lib/process-execution-broker/credential-transport.js +378 -0
  226. package/src/lib/process-execution-broker/index.js +408 -19
  227. package/src/lib/process-execution-broker/platform-sandbox.js +561 -21
  228. package/src/lib/process-execution-broker/windows-sandbox.ps1 +999 -0
  229. package/src/lib/project-mcp-trust.js +21 -26
  230. package/src/lib/protocol-replay.js +19 -12
  231. package/src/lib/settings-hooks.cjs +13 -0
  232. package/src/lib/skill-loader.js +83 -10
  233. package/src/lib/sync-credentials.js +5 -4
  234. package/src/lib/turn-binding.js +8 -6
  235. package/src/repl/agent-repl.js +113 -28
  236. package/src/repl/repl-turn-binding.js +5 -2
  237. package/src/runtime/agent-core.js +331 -26
  238. package/src/runtime/coding-agent-contract-shared.cjs +3 -3
  239. package/src/runtime/headless-runner.js +101 -4
  240. package/src/runtime/headless-stream.js +209 -23
  241. package/src/runtime/mcp-config.js +29 -17
  242. package/src/runtime/policies/agent-policy.js +2 -0
  243. package/src/workers/background-agent-worker.js +128 -13
  244. package/src/assets/web-panel/assets/ChatBubbleRenderer-DvySUzxJ.js +0 -1
  245. package/src/assets/web-panel/assets/MarkdownRenderer-DkxCweb1.js +0 -1
  246. package/src/assets/web-panel/assets/Projects-ClomCrN0.js +0 -1
  247. package/src/assets/web-panel/assets/RemoteSession-pRgaWsUK.js +0 -4
  248. package/src/assets/web-panel/assets/chat-Bvl-ojg2.js +0 -1
  249. package/src/assets/web-panel/assets/devWarning-CSVgo71Z.js +0 -1
  250. package/src/assets/web-panel/assets/index-DMIWh9fu.js +0 -1
  251. package/src/assets/web-panel/assets/index-ssTvV1l6.js +0 -1
@@ -4,8 +4,8 @@
4
4
  *
5
5
  * 统一拦截所有子进程执行:
6
6
  * - M1: 所有子进程唯一入口,权限检查
7
- * - **P0-1**: 可审计的平台执行计划(macOS Seatbelt / Linux prlimit
8
- * Windows 原生 Job Object 未实现时明确报告 unavailable
7
+ * - **P0-1**: 可审计的平台执行计划(macOS Seatbelt / Linux prlimit /
8
+ * Windows Job Object + Restricted Token
9
9
  * - **P0-1**: 凭据代理 default-on(secrets 永远不裸传给子进程)
10
10
  * - M3: 集成W3C trace context自动传播
11
11
  * - M4: 自动写入Runtime Provenance Ledger (RPL)
@@ -36,9 +36,17 @@ const require = createRequire(import.meta.url);
36
36
  import {
37
37
  applySandbox as _applySandbox,
38
38
  postSpawnSandbox as _postSpawnSandbox,
39
+ SANDBOX_BOUNDARIES,
39
40
  } from "./platform-sandbox.js";
40
41
  import { credentialAgent } from "./credential-agent.js";
41
42
 
43
+ const SUPPORTED_SANDBOX_BOUNDARIES = new Set(Object.values(SANDBOX_BOUNDARIES));
44
+ const SUPPORTED_SANDBOX_PROFILES = new Set([
45
+ "default",
46
+ "strict",
47
+ "network-only",
48
+ ]);
49
+
42
50
  // 延迟导入避免循环依赖
43
51
  let _traceCtx = null;
44
52
  let _rpl = null;
@@ -197,16 +205,91 @@ class ProcessExecutionBroker extends EventEmitter {
197
205
  return process.env.CC_SANDBOX_DISABLE === "1";
198
206
  }
199
207
 
200
- _sandboxUnavailablePlan(command, args, options, reason) {
208
+ /**
209
+ * Normalize the public per-spawn boundary contract. `requiredBoundaries` is
210
+ * retained as a top-level alias so callers can adopt the contract without
211
+ * migrating all spawn options to `sandboxPolicy` in one change.
212
+ *
213
+ * @param {Object} options
214
+ * @returns {{profile: "default"|"strict"|"network-only"|null, requiredBoundaries: string[]}}
215
+ */
216
+ _normalizeSandboxPolicy(options = {}) {
217
+ const rawPolicy = options.sandboxPolicy;
218
+ if (
219
+ rawPolicy !== undefined &&
220
+ (rawPolicy === null ||
221
+ typeof rawPolicy !== "object" ||
222
+ Array.isArray(rawPolicy))
223
+ ) {
224
+ throw this._sandboxBoundaryError(
225
+ "invalid_sandbox_policy",
226
+ "sandboxPolicy must be an object",
227
+ );
228
+ }
229
+
230
+ const direct = options.requiredBoundaries;
231
+ const nested = rawPolicy?.requiredBoundaries;
232
+ for (const [name, value] of [
233
+ ["requiredBoundaries", direct],
234
+ ["sandboxPolicy.requiredBoundaries", nested],
235
+ ]) {
236
+ if (value !== undefined && !Array.isArray(value)) {
237
+ throw this._sandboxBoundaryError(
238
+ "invalid_required_boundaries",
239
+ `${name} must be an array`,
240
+ );
241
+ }
242
+ }
243
+
244
+ const requiredBoundaries = [];
245
+ for (const boundary of [...(direct || []), ...(nested || [])]) {
246
+ if (
247
+ typeof boundary !== "string" ||
248
+ !SUPPORTED_SANDBOX_BOUNDARIES.has(boundary)
249
+ ) {
250
+ throw this._sandboxBoundaryError(
251
+ "invalid_required_boundary",
252
+ `Unsupported sandbox boundary: ${String(boundary)}`,
253
+ {
254
+ requiredBoundaries,
255
+ missingBoundaries: [String(boundary)],
256
+ },
257
+ );
258
+ }
259
+ if (!requiredBoundaries.includes(boundary)) {
260
+ requiredBoundaries.push(boundary);
261
+ }
262
+ }
263
+
264
+ const profile = rawPolicy?.profile ?? null;
265
+ if (profile !== null && !SUPPORTED_SANDBOX_PROFILES.has(profile)) {
266
+ throw this._sandboxBoundaryError(
267
+ "invalid_sandbox_profile",
268
+ `Unsupported sandbox profile: ${String(profile)}`,
269
+ { requiredBoundaries },
270
+ );
271
+ }
272
+ return { profile, requiredBoundaries };
273
+ }
274
+
275
+ _stripSandboxControlOptions(options) {
276
+ delete options.sandboxPolicy;
277
+ delete options.requiredBoundaries;
278
+ }
279
+
280
+ _sandboxUnavailablePlan(command, args, options, reason, sandboxPolicy = {}) {
201
281
  return {
202
282
  contractVersion: 1,
203
283
  applied: false,
204
284
  platform: process.platform,
205
- profile: "default",
285
+ profile: sandboxPolicy.profile || "default",
206
286
  command,
207
287
  args: [...(args || [])],
208
288
  options: { ...options },
209
289
  enforcement: null,
290
+ backend: null,
291
+ guarantees: [],
292
+ requiredBoundaries: [...(sandboxPolicy.requiredBoundaries || [])],
210
293
  reason,
211
294
  postSpawn: { required: false, mode: "none" },
212
295
  };
@@ -219,6 +302,26 @@ class ProcessExecutionBroker extends EventEmitter {
219
302
  return error;
220
303
  }
221
304
 
305
+ _sandboxBoundaryError(reason, message = reason, metadata = {}) {
306
+ const error = this._sandboxError(reason, message);
307
+ error.code = "ERR_PROCESS_SANDBOX_BOUNDARY_UNSATISFIED";
308
+ error.sandboxFailClosed = true;
309
+ error.requiredBoundaries = [...(metadata.requiredBoundaries || [])];
310
+ error.actualGuarantees = [...(metadata.actualGuarantees || [])];
311
+ error.missingBoundaries = [...(metadata.missingBoundaries || [])];
312
+ error.sandboxBackend = metadata.sandboxBackend || null;
313
+ error.sandboxCandidateBackend = metadata.sandboxCandidateBackend || null;
314
+ error.sandboxRuntimeProbe = metadata.sandboxRuntimeProbe
315
+ ? { ...metadata.sandboxRuntimeProbe }
316
+ : null;
317
+ error.sandboxPolicyAttested =
318
+ typeof metadata.sandboxPolicyAttested === "boolean"
319
+ ? metadata.sandboxPolicyAttested
320
+ : null;
321
+ error.sandboxCandidateReason = metadata.sandboxCandidateReason || null;
322
+ return error;
323
+ }
324
+
222
325
  _validateSandboxPlan(plan) {
223
326
  if (!plan || typeof plan !== "object") {
224
327
  throw this._sandboxError(
@@ -262,6 +365,64 @@ class ProcessExecutionBroker extends EventEmitter {
262
365
  "Unavailable sandbox spawn plan must provide a reason",
263
366
  );
264
367
  }
368
+ const backend = plan.backend ?? plan.enforcement ?? null;
369
+ if (plan.applied && typeof backend !== "string") {
370
+ throw this._sandboxError(
371
+ "invalid_sandbox_plan",
372
+ "Applied sandbox spawn plan must name its backend",
373
+ );
374
+ }
375
+ const guarantees = plan.guarantees ?? [];
376
+ if (
377
+ !Array.isArray(guarantees) ||
378
+ guarantees.some(
379
+ (boundary) =>
380
+ typeof boundary !== "string" ||
381
+ !SUPPORTED_SANDBOX_BOUNDARIES.has(boundary),
382
+ )
383
+ ) {
384
+ throw this._sandboxError(
385
+ "invalid_sandbox_plan",
386
+ "Sandbox spawn plan guarantees must use supported boundary identifiers",
387
+ );
388
+ }
389
+ const candidateBackend = plan.candidateBackend ?? null;
390
+ if (candidateBackend !== null && typeof candidateBackend !== "string") {
391
+ throw this._sandboxError(
392
+ "invalid_sandbox_plan",
393
+ "Sandbox candidate backend must be a string",
394
+ );
395
+ }
396
+ const policyAttested = plan.policyAttested ?? null;
397
+ if (policyAttested !== null && typeof policyAttested !== "boolean") {
398
+ throw this._sandboxError(
399
+ "invalid_sandbox_plan",
400
+ "Sandbox policy attestation must be boolean",
401
+ );
402
+ }
403
+ let runtimeProbe = null;
404
+ if (plan.runtimeProbe !== null && plan.runtimeProbe !== undefined) {
405
+ if (
406
+ typeof plan.runtimeProbe !== "object" ||
407
+ Array.isArray(plan.runtimeProbe) ||
408
+ typeof plan.runtimeProbe.kind !== "string" ||
409
+ typeof plan.runtimeProbe.attempted !== "boolean" ||
410
+ typeof plan.runtimeProbe.runnable !== "boolean" ||
411
+ (plan.runtimeProbe.reason !== null &&
412
+ typeof plan.runtimeProbe.reason !== "string")
413
+ ) {
414
+ throw this._sandboxError(
415
+ "invalid_sandbox_plan",
416
+ "Sandbox runtime probe must use the typed probe contract",
417
+ );
418
+ }
419
+ runtimeProbe = {
420
+ kind: plan.runtimeProbe.kind,
421
+ attempted: plan.runtimeProbe.attempted,
422
+ runnable: plan.runtimeProbe.runnable,
423
+ reason: plan.runtimeProbe.reason,
424
+ };
425
+ }
265
426
  const postSpawn = plan.postSpawn || { required: false, mode: "none" };
266
427
  if (
267
428
  postSpawn.required &&
@@ -277,12 +438,52 @@ class ProcessExecutionBroker extends EventEmitter {
277
438
  ...plan,
278
439
  args: [...plan.args],
279
440
  options: { ...plan.options },
441
+ backend,
442
+ guarantees: [...new Set(guarantees)],
443
+ candidateBackend,
444
+ policyAttested,
445
+ runtimeProbe,
280
446
  postSpawn: { ...postSpawn },
281
447
  };
282
448
  }
283
449
 
284
- _prepareSandboxPlan(command, args, options, { sync = false } = {}) {
450
+ _assertRequiredSandboxBoundaries(plan, requiredBoundaries) {
451
+ const actualGuarantees = plan.applied ? plan.guarantees : [];
452
+ const guaranteed = new Set(actualGuarantees);
453
+ const missingBoundaries = requiredBoundaries.filter(
454
+ (boundary) => !guaranteed.has(boundary),
455
+ );
456
+ if (missingBoundaries.length > 0) {
457
+ throw this._sandboxBoundaryError(
458
+ "required_boundaries_unsatisfied",
459
+ `Sandbox backend ${plan.backend || plan.candidateBackend || "unavailable"} cannot satisfy required boundaries: ${missingBoundaries.join(", ")}`,
460
+ {
461
+ requiredBoundaries,
462
+ actualGuarantees,
463
+ missingBoundaries,
464
+ sandboxBackend: plan.backend,
465
+ sandboxCandidateBackend: plan.candidateBackend,
466
+ sandboxRuntimeProbe: plan.runtimeProbe,
467
+ sandboxPolicyAttested: plan.policyAttested,
468
+ sandboxCandidateReason: plan.candidateBackend ? plan.reason : null,
469
+ },
470
+ );
471
+ }
472
+ return {
473
+ ...plan,
474
+ requiredBoundaries: [...requiredBoundaries],
475
+ };
476
+ }
477
+
478
+ _prepareSandboxPlan(
479
+ command,
480
+ args,
481
+ options,
482
+ { sync = false, sandboxPolicy = {} } = {},
483
+ ) {
285
484
  const strict = this._sandboxStrictEnabled();
485
+ const requiredBoundaries = sandboxPolicy.requiredBoundaries || [];
486
+ const profile = strict ? "strict" : sandboxPolicy.profile || "default";
286
487
  let disabledReason = null;
287
488
  if (this._sandboxDisabledByEnvironment()) {
288
489
  disabledReason = "disabled_by_environment";
@@ -300,22 +501,37 @@ class ProcessExecutionBroker extends EventEmitter {
300
501
  `Sandbox is unavailable in strict mode: ${disabledReason}`,
301
502
  );
302
503
  }
303
- return this._sandboxUnavailablePlan(
504
+ const unavailablePlan = this._sandboxUnavailablePlan(
304
505
  command,
305
506
  args,
306
507
  options,
307
508
  disabledReason,
509
+ { ...sandboxPolicy, profile },
510
+ );
511
+ return this._assertRequiredSandboxBoundaries(
512
+ unavailablePlan,
513
+ requiredBoundaries,
308
514
  );
309
515
  }
310
516
 
311
- const plan = this._validateSandboxPlan(
517
+ const adapterRequest = Object.freeze({
518
+ profile,
519
+ requiredBoundaries: Object.freeze([...requiredBoundaries]),
520
+ });
521
+ let plan = this._validateSandboxPlan(
522
+ // Keep the legacy string profile in argument four. The built-in adapter
523
+ // reserves argument five for runtime injection, so the typed request is
524
+ // additive in argument six and legacy injected adapters can ignore it.
312
525
  this._sandboxAdapter.applySandbox(
313
526
  command,
314
527
  args || [],
315
528
  options,
316
- "default",
529
+ profile,
530
+ undefined,
531
+ adapterRequest,
317
532
  ),
318
533
  );
534
+ plan = this._assertRequiredSandboxBoundaries(plan, requiredBoundaries);
319
535
 
320
536
  if (!plan.applied && strict) {
321
537
  throw this._sandboxError(
@@ -339,10 +555,13 @@ class ProcessExecutionBroker extends EventEmitter {
339
555
  "spawnSync cannot satisfy required post-spawn sandbox enforcement",
340
556
  );
341
557
  }
342
- if (strict && plan.postSpawn.mode !== "sync") {
558
+ if (
559
+ (strict || requiredBoundaries.length > 0) &&
560
+ plan.postSpawn.mode !== "sync"
561
+ ) {
343
562
  throw this._sandboxError(
344
563
  "async_post_spawn_disallowed_in_strict_mode",
345
- "Strict sandbox mode requires synchronous post-spawn enforcement",
564
+ "Fail-closed sandbox enforcement requires synchronous post-spawn enforcement",
346
565
  );
347
566
  }
348
567
  }
@@ -352,6 +571,18 @@ class ProcessExecutionBroker extends EventEmitter {
352
571
  _applySandboxAudit(auditEntry, plan, applied) {
353
572
  auditEntry.sandboxed = applied;
354
573
  auditEntry.sandboxProfile = plan?.profile || null;
574
+ auditEntry.sandboxRequired = [...(plan?.requiredBoundaries || [])];
575
+ auditEntry.sandboxGuarantees = applied ? [...(plan?.guarantees || [])] : [];
576
+ auditEntry.sandboxBackend = plan?.backend || null;
577
+ auditEntry.sandboxCandidateBackend = plan?.candidateBackend || null;
578
+ auditEntry.sandboxRuntimeProbe = plan?.runtimeProbe
579
+ ? { ...plan.runtimeProbe }
580
+ : null;
581
+ auditEntry.sandboxPolicyAttested =
582
+ typeof plan?.policyAttested === "boolean" ? plan.policyAttested : null;
583
+ auditEntry.sandboxCandidateReason = plan?.candidateBackend
584
+ ? plan?.reason || null
585
+ : null;
355
586
  auditEntry.sandboxEnforcement = applied
356
587
  ? plan?.enforcement || "platform"
357
588
  : null;
@@ -365,6 +596,28 @@ class ProcessExecutionBroker extends EventEmitter {
365
596
  auditEntry.sandboxState = "denied";
366
597
  auditEntry.sandboxReason =
367
598
  error.sandboxReason || "sandbox_initialization_failed";
599
+ auditEntry.sandboxRequired = [
600
+ ...(error.requiredBoundaries || auditEntry.sandboxRequired || []),
601
+ ];
602
+ auditEntry.sandboxGuarantees = [
603
+ ...(error.actualGuarantees || auditEntry.sandboxGuarantees || []),
604
+ ];
605
+ auditEntry.sandboxMissing = [...(error.missingBoundaries || [])];
606
+ auditEntry.sandboxBackend =
607
+ error.sandboxBackend || auditEntry.sandboxBackend || null;
608
+ auditEntry.sandboxCandidateBackend =
609
+ error.sandboxCandidateBackend ||
610
+ auditEntry.sandboxCandidateBackend ||
611
+ null;
612
+ auditEntry.sandboxRuntimeProbe = error.sandboxRuntimeProbe
613
+ ? { ...error.sandboxRuntimeProbe }
614
+ : auditEntry.sandboxRuntimeProbe || null;
615
+ auditEntry.sandboxPolicyAttested =
616
+ typeof error.sandboxPolicyAttested === "boolean"
617
+ ? error.sandboxPolicyAttested
618
+ : (auditEntry.sandboxPolicyAttested ?? null);
619
+ auditEntry.sandboxCandidateReason =
620
+ error.sandboxCandidateReason || auditEntry.sandboxCandidateReason || null;
368
621
  auditEntry.deniedReason = `sandbox-init-failed: ${error.message}`;
369
622
  auditEntry.endTime = Date.now();
370
623
  auditEntry.durationMs = auditEntry.endTime - startTime;
@@ -391,7 +644,11 @@ class ProcessExecutionBroker extends EventEmitter {
391
644
  if (!plan.applied || !plan.postSpawn.required) {
392
645
  this._applySandboxAudit(auditEntry, plan, plan.applied);
393
646
  if (plan.applied) this._stats.sandboxed++;
394
- const ready = Promise.resolve({ applied: plan.applied });
647
+ const ready = Promise.resolve({
648
+ applied: plan.applied,
649
+ backend: plan.backend,
650
+ guarantees: plan.applied ? [...plan.guarantees] : [],
651
+ });
395
652
  proc.sandboxReady = ready;
396
653
  return;
397
654
  }
@@ -403,7 +660,7 @@ class ProcessExecutionBroker extends EventEmitter {
403
660
  this._applySandboxAudit(auditEntry, plan, false);
404
661
  auditEntry.sandboxState = "failed";
405
662
  auditEntry.sandboxReason = `post_spawn_failed: ${error.message}`;
406
- if (this._sandboxStrictEnabled()) {
663
+ if (this._sandboxStrictEnabled() || plan.requiredBoundaries.length > 0) {
407
664
  if (typeof proc.once === "function") proc.once("error", () => {});
408
665
  try {
409
666
  proc.kill?.();
@@ -423,7 +680,7 @@ class ProcessExecutionBroker extends EventEmitter {
423
680
  }
424
681
 
425
682
  if (postSpawnResult && typeof postSpawnResult.then === "function") {
426
- if (this._sandboxStrictEnabled()) {
683
+ if (this._sandboxStrictEnabled() || plan.requiredBoundaries.length > 0) {
427
684
  Promise.resolve(postSpawnResult).catch(() => {});
428
685
  if (typeof proc.once === "function") proc.once("error", () => {});
429
686
  try {
@@ -442,7 +699,11 @@ class ProcessExecutionBroker extends EventEmitter {
442
699
  () => {
443
700
  this._applySandboxAudit(auditEntry, plan, true);
444
701
  this._stats.sandboxed++;
445
- return { applied: true };
702
+ return {
703
+ applied: true,
704
+ backend: plan.backend,
705
+ guarantees: [...plan.guarantees],
706
+ };
446
707
  },
447
708
  (error) => {
448
709
  this._applySandboxAudit(auditEntry, plan, false);
@@ -463,7 +724,11 @@ class ProcessExecutionBroker extends EventEmitter {
463
724
 
464
725
  this._applySandboxAudit(auditEntry, plan, true);
465
726
  this._stats.sandboxed++;
466
- proc.sandboxReady = Promise.resolve({ applied: true });
727
+ proc.sandboxReady = Promise.resolve({
728
+ applied: true,
729
+ backend: plan.backend,
730
+ guarantees: [...plan.guarantees],
731
+ });
467
732
  }
468
733
 
469
734
  _credentialBoundaryEnabled() {
@@ -527,6 +792,35 @@ class ProcessExecutionBroker extends EventEmitter {
527
792
  };
528
793
  }
529
794
 
795
+ _createCredentialContext(command, options, executionId, decision) {
796
+ if (typeof this._credentialAgent.createBrokerContext !== "function") {
797
+ return options.credentialContext;
798
+ }
799
+ const supplied = options.credentialContext || {};
800
+ return this._credentialAgent.createBrokerContext({
801
+ approvalId: `${executionId}:${decision}`,
802
+ process: command,
803
+ host:
804
+ supplied.target?.host ??
805
+ supplied.host ??
806
+ options.credentialTarget?.host ??
807
+ options.credentialTargetHost ??
808
+ null,
809
+ ttlMs: supplied.ttlMs ?? options.credentialTtlMs,
810
+ maxUses: supplied.maxUses ?? options.credentialMaxUses,
811
+ });
812
+ }
813
+
814
+ _stripCredentialControlOptions(options) {
815
+ delete options.credentialContext;
816
+ delete options.credentialApproved;
817
+ delete options.credentialApprovalId;
818
+ delete options.credentialTarget;
819
+ delete options.credentialTargetHost;
820
+ delete options.credentialTtlMs;
821
+ delete options.credentialMaxUses;
822
+ }
823
+
530
824
  _recordCredentialReport(auditEntry, report) {
531
825
  const filtered = report?.filtered === true;
532
826
  auditEntry.credentialFiltered = filtered;
@@ -629,8 +923,21 @@ class ProcessExecutionBroker extends EventEmitter {
629
923
  pluginId: options.pluginId || null,
630
924
  pluginVersion: options.pluginVersion || null,
631
925
  pluginSource: options.pluginSource || null,
926
+ sandboxRequired: [],
927
+ sandboxGuarantees: [],
928
+ sandboxBackend: null,
632
929
  };
633
930
 
931
+ let sandboxPolicy;
932
+ try {
933
+ sandboxPolicy = this._normalizeSandboxPolicy(options);
934
+ auditEntry.sandboxRequired = [...sandboxPolicy.requiredBoundaries];
935
+ } catch (sandboxPolicyError) {
936
+ this._recordSandboxDenial(auditEntry, sandboxPolicyError, startTime);
937
+ sandboxPolicyError.auditEntry = auditEntry;
938
+ throw sandboxPolicyError;
939
+ }
940
+
634
941
  if (decision === "deny" || decision === "prompt") {
635
942
  auditEntry.deniedReason = isDangerous
636
943
  ? "dangerous_command"
@@ -658,6 +965,7 @@ class ProcessExecutionBroker extends EventEmitter {
658
965
 
659
966
  // 传播traceparent环境变量
660
967
  const spawnOpts = this._sanitizeOptions(options);
968
+ this._stripSandboxControlOptions(spawnOpts);
661
969
  if (traceCtx) {
662
970
  spawnOpts.env = { ...(spawnOpts.env || process.env) };
663
971
  spawnOpts.env.TRACEPARENT = traceCtx.traceparent;
@@ -665,6 +973,12 @@ class ProcessExecutionBroker extends EventEmitter {
665
973
 
666
974
  // P0-1: Credential filtering (default-on) — strip secrets from env/args
667
975
  if (this._credentialBoundaryEnabled()) {
976
+ spawnOpts.credentialContext = this._createCredentialContext(
977
+ command,
978
+ spawnOpts,
979
+ executionId,
980
+ decision,
981
+ );
668
982
  const credentialBoundary = this._applyCredentialBoundary(
669
983
  command,
670
984
  args,
@@ -675,14 +989,21 @@ class ProcessExecutionBroker extends EventEmitter {
675
989
  args = credentialBoundary.args;
676
990
  auditEntry.args = [...args];
677
991
  this._recordCredentialReport(auditEntry, credentialBoundary.report);
992
+ this._stripCredentialControlOptions(spawnOpts);
678
993
  }
679
994
 
680
995
  // P0-1: Platform sandbox wrapping — apply macOS/Windows/Linux sandbox
681
996
  let sandboxPlan;
682
997
  try {
683
- sandboxPlan = this._prepareSandboxPlan(command, args || [], spawnOpts);
998
+ sandboxPlan = this._prepareSandboxPlan(command, args || [], spawnOpts, {
999
+ sandboxPolicy,
1000
+ });
684
1001
  } catch (sandboxErr) {
685
- if (this._sandboxStrictEnabled()) {
1002
+ if (
1003
+ this._sandboxStrictEnabled() ||
1004
+ sandboxErr.sandboxFailClosed ||
1005
+ sandboxPolicy.requiredBoundaries.length > 0
1006
+ ) {
686
1007
  this._recordSandboxDenial(auditEntry, sandboxErr, startTime);
687
1008
  sandboxErr.auditEntry = auditEntry;
688
1009
  throw sandboxErr;
@@ -695,6 +1016,7 @@ class ProcessExecutionBroker extends EventEmitter {
695
1016
  args || [],
696
1017
  spawnOpts,
697
1018
  `sandbox_init_failed: ${sandboxErr.message}`,
1019
+ sandboxPolicy,
698
1020
  );
699
1021
  }
700
1022
  command = sandboxPlan.command;
@@ -722,6 +1044,13 @@ class ProcessExecutionBroker extends EventEmitter {
722
1044
  );
723
1045
  try {
724
1046
  this._runPostSpawnSandbox(proc, sandboxPlan, auditEntry);
1047
+ auditEntry.pid = proc.pid;
1048
+ if (Number.isSafeInteger(proc.sandboxWrapperPid)) {
1049
+ auditEntry.sandboxWrapperPid = proc.sandboxWrapperPid;
1050
+ }
1051
+ if (Number.isSafeInteger(proc.sandboxTargetPid)) {
1052
+ auditEntry.sandboxTargetPid = proc.sandboxTargetPid;
1053
+ }
725
1054
  } catch (postSpawnError) {
726
1055
  cleanupSandbox();
727
1056
  this._recordSandboxDenial(auditEntry, postSpawnError, startTime);
@@ -809,8 +1138,21 @@ class ProcessExecutionBroker extends EventEmitter {
809
1138
  pluginId: options.pluginId || null,
810
1139
  pluginVersion: options.pluginVersion || null,
811
1140
  pluginSource: options.pluginSource || null,
1141
+ sandboxRequired: [],
1142
+ sandboxGuarantees: [],
1143
+ sandboxBackend: null,
812
1144
  };
813
1145
 
1146
+ let sandboxPolicy;
1147
+ try {
1148
+ sandboxPolicy = this._normalizeSandboxPolicy(options);
1149
+ auditEntry.sandboxRequired = [...sandboxPolicy.requiredBoundaries];
1150
+ } catch (sandboxPolicyError) {
1151
+ this._recordSandboxDenial(auditEntry, sandboxPolicyError, startTime);
1152
+ sandboxPolicyError.auditEntry = auditEntry;
1153
+ throw sandboxPolicyError;
1154
+ }
1155
+
814
1156
  if (decision === "deny" || decision === "prompt") {
815
1157
  auditEntry.deniedReason = isDangerous
816
1158
  ? "dangerous_command"
@@ -831,6 +1173,7 @@ class ProcessExecutionBroker extends EventEmitter {
831
1173
  }
832
1174
 
833
1175
  const spawnOpts = this._sanitizeOptions(options);
1176
+ this._stripSandboxControlOptions(spawnOpts);
834
1177
  if (traceCtx) {
835
1178
  spawnOpts.env = { ...(spawnOpts.env || process.env) };
836
1179
  spawnOpts.env.TRACEPARENT = traceCtx.traceparent;
@@ -838,6 +1181,12 @@ class ProcessExecutionBroker extends EventEmitter {
838
1181
 
839
1182
  // P0-1: Credential filtering agent — strip secrets from env/args before spawn
840
1183
  if (this._credentialBoundaryEnabled()) {
1184
+ spawnOpts.credentialContext = this._createCredentialContext(
1185
+ command,
1186
+ spawnOpts,
1187
+ executionId,
1188
+ decision,
1189
+ );
841
1190
  const credentialBoundary = this._applyCredentialBoundary(
842
1191
  command,
843
1192
  args,
@@ -848,6 +1197,7 @@ class ProcessExecutionBroker extends EventEmitter {
848
1197
  args = credentialBoundary.args;
849
1198
  auditEntry.args = [...args];
850
1199
  this._recordCredentialReport(auditEntry, credentialBoundary.report);
1200
+ this._stripCredentialControlOptions(spawnOpts);
851
1201
  }
852
1202
 
853
1203
  // P0-1: Platform sandbox wrapping (sync path)
@@ -855,9 +1205,14 @@ class ProcessExecutionBroker extends EventEmitter {
855
1205
  try {
856
1206
  sandboxPlan = this._prepareSandboxPlan(command, args || [], spawnOpts, {
857
1207
  sync: true,
1208
+ sandboxPolicy,
858
1209
  });
859
1210
  } catch (sandboxErr) {
860
- if (this._sandboxStrictEnabled()) {
1211
+ if (
1212
+ this._sandboxStrictEnabled() ||
1213
+ sandboxErr.sandboxFailClosed ||
1214
+ sandboxPolicy.requiredBoundaries.length > 0
1215
+ ) {
861
1216
  this._recordSandboxDenial(auditEntry, sandboxErr, startTime);
862
1217
  sandboxErr.auditEntry = auditEntry;
863
1218
  throw sandboxErr;
@@ -870,6 +1225,7 @@ class ProcessExecutionBroker extends EventEmitter {
870
1225
  args || [],
871
1226
  spawnOpts,
872
1227
  `sandbox_init_failed: ${sandboxErr.message}`,
1228
+ sandboxPolicy,
873
1229
  );
874
1230
  }
875
1231
  command = sandboxPlan.command;
@@ -929,10 +1285,22 @@ class ProcessExecutionBroker extends EventEmitter {
929
1285
  pty: true,
930
1286
  sandboxed: false,
931
1287
  sandboxReason: "native_pty_host_boundary",
1288
+ sandboxRequired: [],
1289
+ sandboxGuarantees: [],
1290
+ sandboxBackend: null,
932
1291
  pluginId: options.pluginId || null,
933
1292
  pluginVersion: options.pluginVersion || null,
934
1293
  pluginSource: options.pluginSource || null,
935
1294
  };
1295
+ let sandboxPolicy;
1296
+ try {
1297
+ sandboxPolicy = this._normalizeSandboxPolicy(options);
1298
+ auditEntry.sandboxRequired = [...sandboxPolicy.requiredBoundaries];
1299
+ } catch (sandboxPolicyError) {
1300
+ this._recordSandboxDenial(auditEntry, sandboxPolicyError, startTime);
1301
+ sandboxPolicyError.auditEntry = auditEntry;
1302
+ throw sandboxPolicyError;
1303
+ }
936
1304
  if (policy === "deny" || policy === "prompt") {
937
1305
  auditEntry.deniedReason = `policy_${policy}`;
938
1306
  auditEntry.endTime = Date.now();
@@ -947,8 +1315,22 @@ class ProcessExecutionBroker extends EventEmitter {
947
1315
  error.auditEntry = auditEntry;
948
1316
  throw error;
949
1317
  }
1318
+ if (sandboxPolicy.requiredBoundaries.length > 0) {
1319
+ const sandboxError = this._sandboxBoundaryError(
1320
+ "required_boundaries_unsatisfied",
1321
+ `Native PTY host cannot satisfy required boundaries: ${sandboxPolicy.requiredBoundaries.join(", ")}`,
1322
+ {
1323
+ requiredBoundaries: sandboxPolicy.requiredBoundaries,
1324
+ missingBoundaries: sandboxPolicy.requiredBoundaries,
1325
+ },
1326
+ );
1327
+ this._recordSandboxDenial(auditEntry, sandboxError, startTime);
1328
+ sandboxError.auditEntry = auditEntry;
1329
+ throw sandboxError;
1330
+ }
950
1331
 
951
1332
  const spawnOptions = { ...options, args: [...auditEntry.args] };
1333
+ this._stripSandboxControlOptions(spawnOptions);
952
1334
  delete spawnOptions.origin;
953
1335
  delete spawnOptions.policy;
954
1336
  delete spawnOptions.scope;
@@ -957,6 +1339,12 @@ class ProcessExecutionBroker extends EventEmitter {
957
1339
  delete spawnOptions.pluginSource;
958
1340
  try {
959
1341
  if (this._credentialBoundaryEnabled()) {
1342
+ spawnOptions.credentialContext = this._createCredentialContext(
1343
+ command,
1344
+ spawnOptions,
1345
+ executionId,
1346
+ policy,
1347
+ );
960
1348
  const credentialBoundary = this._applyCredentialBoundary(
961
1349
  command,
962
1350
  args,
@@ -967,6 +1355,7 @@ class ProcessExecutionBroker extends EventEmitter {
967
1355
  spawnOptions.args = credentialBoundary.args;
968
1356
  auditEntry.args = [...credentialBoundary.args];
969
1357
  this._recordCredentialReport(auditEntry, credentialBoundary.report);
1358
+ this._stripCredentialControlOptions(spawnOptions);
970
1359
  }
971
1360
  const filteredArgs = spawnOptions.args || [];
972
1361
  delete spawnOptions.args;
@@ -1156,5 +1545,5 @@ class ProcessExecutionBroker extends EventEmitter {
1156
1545
  }
1157
1546
 
1158
1547
  const broker = new ProcessExecutionBroker();
1159
- export { broker as executionBroker };
1548
+ export { broker as executionBroker, SANDBOX_BOUNDARIES };
1160
1549
  export default broker;