chainlesschain 0.163.8 → 0.165.1

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 (240) hide show
  1. package/package.json +7 -4
  2. package/scripts/macos-mcp-launcher-build.mjs +317 -0
  3. package/scripts/macos-mcp-launcher-postinstall.sh +54 -0
  4. package/scripts/macos-mcp-launcher-preinstall.sh +61 -0
  5. package/src/assets/web-panel/.build-hash +1 -1
  6. package/src/assets/web-panel/assets/{AIOps-CavM7W3k.js → AIOps-CYxFDrcm.js} +1 -1
  7. package/src/assets/web-panel/assets/{ActionButton-CUvZGabQ.js → ActionButton-CPBtdiU2.js} +1 -1
  8. package/src/assets/web-panel/assets/{Analytics-DeBnWnbe.js → Analytics-Dayq7Dp7.js} +3 -3
  9. package/src/assets/web-panel/assets/{AppLayout-DbI5kxvd.js → AppLayout-6U7bPb2s.js} +4 -4
  10. package/src/assets/web-panel/assets/{Artifacts-D93bigKm.js → Artifacts-D2Iqg_3D.js} +1 -1
  11. package/src/assets/web-panel/assets/{Audit-CBNvfUZa.js → Audit-CdoOB7WV.js} +1 -1
  12. package/src/assets/web-panel/assets/{BackgroundAgents-CJLyh_YU.js → BackgroundAgents-DrnAVB8w.js} +1 -1
  13. package/src/assets/web-panel/assets/{Backup-D_0yoehD.js → Backup-CesMi5cy.js} +1 -1
  14. package/src/assets/web-panel/assets/{BaseInput-TJxmbObW.js → BaseInput-DaX9ptax.js} +1 -1
  15. package/src/assets/web-panel/assets/{Chat-CE0dto1q.js → Chat-OrwOPxDS.js} +5 -5
  16. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CZ5-yYiD.js → ChatBubbleRenderer-CvPZFRxM.js} +1 -1
  17. package/src/assets/web-panel/assets/{Checkbox-Ck1RVIVo.js → Checkbox-DiHbcysC.js} +1 -1
  18. package/src/assets/web-panel/assets/{Codegen-qpoyf6DK.js → Codegen-CbgCkaBJ.js} +1 -1
  19. package/src/assets/web-panel/assets/{Col-DUyPWjIE.js → Col-Du5hgrh4.js} +1 -1
  20. package/src/assets/web-panel/assets/{Community-D_S1BemS.js → Community-DsPOBW-p.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compact-BjxeK-Gc.js → Compact-BwHIFkNC.js} +1 -1
  22. package/src/assets/web-panel/assets/{Compliance-Dd3CEJsu.js → Compliance-BvrDQSgd.js} +1 -1
  23. package/src/assets/web-panel/assets/{Cowork-B4QG7-ad.js → Cowork-gwAE6arx.js} +3 -3
  24. package/src/assets/web-panel/assets/{Cron-BtZnids5.js → Cron-DW-0l4uF.js} +2 -2
  25. package/src/assets/web-panel/assets/{Crosschain-CHPfCBFD.js → Crosschain-j-NsLesB.js} +1 -1
  26. package/src/assets/web-panel/assets/{DID-DT8DCEOK.js → DID-CibVEBOI.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dashboard-COQab5_U.js → Dashboard-W4z9vSfe.js} +2 -2
  28. package/src/assets/web-panel/assets/{Dropdown-BY1PsQuU.js → Dropdown-DAcrkKxG.js} +1 -1
  29. package/src/assets/web-panel/assets/{EmailListRenderer-CsuAuaq3.js → EmailListRenderer-6GXah-89.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-BqpinD-j.js → FamilyGuardDashboard-TKDCq8Ku.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-D0gkfQFv.js → Federation-BXBLlcNm.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-BqgE-axK.js → FormItemContext-BoJJBkG3.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-D0hJ2KvC.js → GenericCardRenderer-okjsl46v.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-CmMB0uPY.js → Git-Rvs7i6nn.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-BnVEI0Dk.js → Governance-CHSUxXXS.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-YTAMihRP.js → Inference-V3BlfxsB.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-0ax7VHop.js → KnowledgeGraph-C_NlD4aR.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-B9TRcokL.js → Logs-Nn4LNxhA.js} +2 -2
  39. package/src/assets/web-panel/assets/MarkdownRenderer-SVAgNnkt.js +1 -0
  40. package/src/assets/web-panel/assets/{Marketplace-B6CSuD_H.js → Marketplace-DEmjFcg-.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-CjMXvOVU.js → McpTools-DlopXipI.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-CXRF71U3.js → Memory-BG3ynX60.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-DQgNp_oS.js → MobileBridge-DeRzWOfT.js} +1 -1
  44. package/src/assets/web-panel/assets/{MobileProjects-DlPwcCbq.js → MobileProjects-Tyd3o2A0.js} +1 -1
  45. package/src/assets/web-panel/assets/{Mtc-6hDTRPe1.js → Mtc-BoPbOv1C.js} +2 -2
  46. package/src/assets/web-panel/assets/{MtcAudit-BlVHU1DS.js → MtcAudit-un-rTHp7.js} +2 -2
  47. package/src/assets/web-panel/assets/{Multisig-DP9pzEbV.js → Multisig-Ds0oveEB.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-Djorh8EV.js → NLProgramming-D09JI-yY.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-oLZ-JkUg.js → Notes-DTRhiKJn.js} +4 -4
  50. package/src/assets/web-panel/assets/{NotificationSettings-Cg288VH3.js → NotificationSettings-BAnnNCim.js} +1 -1
  51. package/src/assets/web-panel/assets/OrderTableRenderer-Yr-1fSYi.js +1 -0
  52. package/src/assets/web-panel/assets/{Organization-CBdo-bHs.js → Organization-S9EAolpj.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-qZdnVumx.js → Overflow-CqcLKqJ8.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-D4kNfGNQ.js → P2P-Dw0F9EcU.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-DnlMemM7.js → PdhVaultBrowser-BDRwUevN.js} +5 -5
  56. package/src/assets/web-panel/assets/{Permissions-DHucHFBJ.js → Permissions-D3_c3nKB.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-BovlOIPR.js → PersonalDataHub-CxdMV98x.js} +4 -4
  58. package/src/assets/web-panel/assets/{Pipeline-Deru3CQY.js → Pipeline-CgjNQFLI.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-Bq5oTTbU.js → Privacy-BHghIIht.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-BfzxVWAz.js → ProjectInit-De6pqaKM.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-CKC6XBtH.js → ProjectSettings-Bg4ZkNYQ.js} +2 -2
  62. package/src/assets/web-panel/assets/Projects-CP8vPvzs.js +1 -0
  63. package/src/assets/web-panel/assets/{Providers-C_jx4TWX.js → Providers-CUnHbNf-.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-BdIHeVGC.js → QrScannerModal-DA2f3Wts.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-BwZwAcPD.js → QuickAsk-C1FeHDqp.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-BNTt0L-m.js → Recommend-B5guaUMN.js} +1 -1
  67. package/src/assets/web-panel/assets/RemoteSession-PDADSds3.js +5 -0
  68. package/src/assets/web-panel/assets/{Reputation-D6VpG32B.js → Reputation-eTlRhgvK.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-D_74OvQQ.js → Row-D7AqSGY0.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-BTr0a-BQ.js → RssFeed-JiuLm4Ja.js} +3 -3
  71. package/src/assets/web-panel/assets/{Search-C3MCFoNU.js → Search-CwruahW3.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-CqW9aJ6s.js → Security-CdhqaR0b.js} +4 -4
  73. package/src/assets/web-panel/assets/{Services-Cw5GNaHF.js → Services-CU0ZIlcT.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-DZps5qeY.js → Skeleton-CtduPfAb.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-C6NQ1znT.js → Skills-CROXm6AY.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-DFP8G2Sh.js → Sla-DiZiABFD.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-ESt6MB6v.js → SpeechSettings-B5pLcXUw.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-BHnN98aM.js → SyncSettings-DBX6J1Oe.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-NiSCaOf-.js → Tasks-BLyRJd3-.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-DsKFhW2C.js → Templates-BKa5qzmk.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-CQ0E0ze5.js → Tenant-DnD3a4M6.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-D_rBu_by.js → Terminal-DEitQeTb.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-D3Vm4Po4.js → TimelineRenderer-CjHggTDq.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-DNTxRH6q.js → Tokens-CsGT7sfl.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-Dgprz1ms.js → Trigger-yr4rFDrW.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-B2rUnVBD.js → Trust-CLvu1Sjp.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-DEGQNc6_.js → UkeySign-B0m7yUP8.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-jlsAx3Eh.js → VideoEditing-C0VvP4lc.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-8jQih1ij.js → Wallet-kllBAG1M.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-XLeO6xIB.js → WebAuthn-C54UQNLx.js} +3 -3
  91. package/src/assets/web-panel/assets/{WorkflowEditor-De_dgDAG.js → WorkflowEditor-B7y8qSvU.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-CI19R_Sk.js → chat-DRzTh8CJ.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-DsYTOYN3.js → colors-BSMwSnCx.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-CM3-t_Qr.js → compact-item-BTg602H5.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-BjxlBRZv.js → createContext-B6EGsdvp.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-Dol8jLEP.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-RDaWX_4i.js → hasIn-DDKqJ8RD.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-nAH87mQP.js → index-323Hhxxt.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-DIUnNOjG.js → index-BICn3Qh1.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DyIWssPC.js → index-BMuGd2--.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DX7tuWVJ.js → index-BRqt4fO-.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-Cd3euP_4.js → index-BVTAl5N2.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-Cpqm1qfU.js → index-BsR7Y2NG.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-DcPFB8qJ.js → index-Bx044qDj.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-Cd9OJhHG.js → index-C1GFfuqN.js} +1 -1
  106. package/src/assets/web-panel/assets/index-C3QX5tOl.js +1 -0
  107. package/src/assets/web-panel/assets/{index-B-Z8eFUJ.js → index-C66NpWy5.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BlT2VAEK.js → index-CDTvsX8t.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Dsij_KsN.js → index-CGNklbP6.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-C4gkzxkw.js → index-CHfLYwcW.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-D6sm5-Xq.js → index-CNxg61YP.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-C0yx-jtQ.js → index-CQlHFN_g.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-CjTrRt13.js → index-CUEU48o1.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-B7WBt_4T.js → index-CWGax2QW.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-IeiL9RKc.js → index-C_JzIXUq.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CnHH7bnD.js → index-Cf23wVMs.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BKJr-TZp.js → index-CmAInUkX.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CiECJi-Q.js → index-CmAubjDi.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BCnZyIMA.js → index-Co7oM1qr.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Drlnwr8F.js → index-CwPUZbMI.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-9R6BxAr0.js → index-D1naNj4U.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-BGqqJfL0.js → index-D5CsBShd.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-Bi46Xu4u.js → index-DBT3YeQ9.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DXXtGMUJ.js → index-DLdrHhML.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-B0PMlbMs.js → index-Dc77VR3H.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-D0zcy54x.js → index-Dfv2lKu3.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BN6UPD2E.js → index-DiW0sDkz.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Dxge-xWl.js → index-DpTHIRfZ.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CyOGN6a5.js → index-DqFXGzzC.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-B9O9YyWE.js → index-XFe-1twF.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-BHNYPO0b.js → index-p2HYn89m.js} +3 -3
  132. package/src/assets/web-panel/assets/{index-CVQMeiwH.js → index-pqfux8vZ.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-pPL66J85.js → index-rjzk9z1Q.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-DoQA0-52.js → index-th2ihDc0.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-B5REnKt8.js → index-u2YVld9W.js} +1 -1
  136. package/src/assets/web-panel/assets/index-xYybvEic.js +1 -0
  137. package/src/assets/web-panel/assets/{initDefaultProps-BTL88of4.js → initDefaultProps-C3Djh9fa.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-BUB2pXwB.js → motion-BzqFmbSe.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-egCkkOMm.js → move-DJo_FFaW.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-DAWhZC8c.js → mtc-parser-_tlTiBvk.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-CvOxe_6d.js → omit-CB2ZyxUg.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-DZUSLZ5Z.js → pickAttrs-DZwIFD4u.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-BERxGNMY.js → placementArrow-DxZY0dgk.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-DZuDfZ9n.js → responsiveObserve-CzzGt7GL.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-DO756sgI.js → slide-BaIK52yz.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-BRQlIz28.js → statusUtils-3-FHu9_M.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-DCSfdybl.js → styleChecker-BkRT68fK.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-LD8dWVve.js → useFlexGapSupport-DHYwKS-s.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-BX9uW2LK.js → useFs-DVVUhV8p.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-BPSlPuHU.js → usePersonalDataHub-CkrFKAzQ.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-BmOILC9V.js → vnode-BuBLFz0c.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-1iKowKGg.js → zoom-kpm6LtXU.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/command-help-index.json +3 -3
  155. package/src/commands/cowork.js +418 -41
  156. package/src/commands/permissions.js +240 -16
  157. package/src/commands/plugin.js +1293 -56
  158. package/src/commands/session-location.js +276 -0
  159. package/src/commands/session.js +2 -0
  160. package/src/data/changelog.json +28 -2
  161. package/src/gateways/ws/action-protocol.js +316 -17
  162. package/src/gateways/ws/message-dispatcher.js +30 -0
  163. package/src/gateways/ws/remote-session-protocol.js +565 -35
  164. package/src/gateways/ws/ws-agent-handler.js +12 -0
  165. package/src/gateways/ws/ws-approval-gate.js +5 -0
  166. package/src/gateways/ws/ws-server.js +510 -50
  167. package/src/harness/jsonl-session-store.js +341 -24
  168. package/src/harness/mcp-client.js +8 -1
  169. package/src/harness/remote-session-audit.js +2 -0
  170. package/src/harness/remote-session-crypto.js +929 -21
  171. package/src/harness/remote-session-registry.js +945 -24
  172. package/src/harness/session-list-index.js +233 -14
  173. package/src/lib/agent-authority.js +6 -0
  174. package/src/lib/auto-mode-config.js +98 -3
  175. package/src/lib/background-agent-keeper-client.js +248 -0
  176. package/src/lib/background-agent-keeper-protocol.js +291 -0
  177. package/src/lib/background-agent-supervisor.js +1357 -85
  178. package/src/lib/background-interaction-resolver.js +12 -0
  179. package/src/lib/background-session-transport.js +23 -6
  180. package/src/lib/background-turn-bootstrap-protocol.js +190 -0
  181. package/src/lib/cowork-workflow.js +1188 -76
  182. package/src/lib/delivery-production-adapter.js +38 -2
  183. package/src/lib/dynamic-workflow-facade.js +1736 -0
  184. package/src/lib/execution-location-contract.js +551 -0
  185. package/src/lib/execution-location-runtime.js +130 -0
  186. package/src/lib/ide-context.js +94 -6
  187. package/src/lib/mcp-stdio-package-materialization.js +166 -14
  188. package/src/lib/packer/pkg-config-generator.js +2 -0
  189. package/src/lib/permission-authority.js +77 -0
  190. package/src/lib/permission-side-effect-center.js +495 -0
  191. package/src/lib/plugin-runtime/install.js +514 -13
  192. package/src/lib/plugin-runtime/marketplace-artifact-readback.js +900 -0
  193. package/src/lib/plugin-runtime/marketplace-catalog.js +1181 -0
  194. package/src/lib/plugin-runtime/marketplace-impact.js +408 -0
  195. package/src/lib/plugin-runtime/marketplace-remote-artifacts.js +1567 -0
  196. package/src/lib/plugin-security.js +60 -3
  197. package/src/lib/process-execution-broker/index.js +1095 -57
  198. package/src/lib/process-execution-broker/linux-bwrap-descriptor-launch.js +375 -0
  199. package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +90 -16
  200. package/src/lib/process-execution-broker/linux-generic-bwrap.js +159 -18
  201. package/src/lib/process-execution-broker/macos-mcp-launcher-contract.js +278 -0
  202. package/src/lib/process-execution-broker/macos-mcp-launcher-protocol.json +23 -0
  203. package/src/lib/process-execution-broker/macos-mcp-launcher.c +1497 -0
  204. package/src/lib/process-execution-broker/mcp-fd-entry-bootstrap.js +37 -0
  205. package/src/lib/process-execution-broker/platform-sandbox.js +2330 -279
  206. package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
  207. package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
  208. package/src/lib/process-execution-broker/windows-sandbox.cs +50 -4
  209. package/src/lib/public-ide-capability-manifest.js +3 -0
  210. package/src/lib/remote-approval-bridge.js +777 -34
  211. package/src/lib/remote-control.js +2 -0
  212. package/src/lib/remote-membership-authority.js +632 -0
  213. package/src/lib/remote-membership-coordinator.js +2973 -0
  214. package/src/lib/remote-membership-host-store.js +1799 -0
  215. package/src/lib/runtime-provenance-ledger.js +171 -46
  216. package/src/lib/scoped-permission-store.js +369 -0
  217. package/src/lib/session-anti-rollback-anchor.js +262 -5
  218. package/src/lib/shell-approval.js +169 -6
  219. package/src/lib/sub-agent-context.js +4 -0
  220. package/src/lib/with-file-lock.js +73 -38
  221. package/src/lib/workflow-definition-contract.js +149 -0
  222. package/src/repl/agent-repl.js +111 -36
  223. package/src/repl/chat-repl.js +2 -0
  224. package/src/repl/clipboard-image.js +735 -16
  225. package/src/repl/ide-status.js +1 -1
  226. package/src/repl/prompt-interactions.js +59 -6
  227. package/src/repl/remote-approval.js +29 -7
  228. package/src/runtime/agent-core.js +1182 -155
  229. package/src/runtime/headless-runner.js +52 -30
  230. package/src/runtime/headless-stream.js +51 -28
  231. package/src/workers/background-agent-keeper.js +689 -0
  232. package/src/workers/background-agent-worker.js +365 -13
  233. package/src/workers/background-turn-bootstrap.js +170 -0
  234. package/src/assets/web-panel/assets/MarkdownRenderer-yySN5YNM.js +0 -1
  235. package/src/assets/web-panel/assets/OrderTableRenderer-Bb1O3Ofr.js +0 -1
  236. package/src/assets/web-panel/assets/Projects-CMolGhae.js +0 -1
  237. package/src/assets/web-panel/assets/RemoteSession-Biyn2-Ro.js +0 -5
  238. package/src/assets/web-panel/assets/devWarning-S1ld2LwU.js +0 -1
  239. package/src/assets/web-panel/assets/index-Drz6yq0m.js +0 -1
  240. package/src/assets/web-panel/assets/index-uWiUs7S_.js +0 -1
@@ -0,0 +1,375 @@
1
+ /**
2
+ * Descriptor-bound pre-exec launcher shared by the Linux bubblewrap backends.
3
+ *
4
+ * Node maps every declared stdio entry onto a contiguous child descriptor.
5
+ * The pinned Bash executable is appended after that declared range. Bash then
6
+ * closes its own descriptor and every unknown inherited descriptor above the
7
+ * range before executing the already-pinned target executable by descriptor.
8
+ */
9
+
10
+ import crypto from "node:crypto";
11
+
12
+ export const LINUX_BWRAP_DESCRIPTOR_SCRUBBER_PATH = "/usr/bin/bash";
13
+ export const LINUX_BWRAP_DESCRIPTOR_SCRUBBER_KIND =
14
+ "linux-bwrap-inherited-fd-scrubber-v1";
15
+ export const LINUX_BWRAP_DESCRIPTOR_SCRUBBER_MECHANISM =
16
+ "pinned-root-owned-bash-appended-fd-three-pass-proc-self-fd-sweep-v1";
17
+ export const LINUX_BWRAP_DESCRIPTOR_SCRUBBER_ARGV0 =
18
+ "chainless-bwrap-fd-scrubber-v1";
19
+ export const LINUX_BWRAP_DESCRIPTOR_SCRUBBER_PASSES = 3;
20
+ export const LINUX_BWRAP_DESCRIPTOR_SCRUBBER_FAILURE_STATUS = 125;
21
+
22
+ // This script is fixed application code. Values derived from a launch plan are
23
+ // passed only as positional arguments and are validated as decimal integers;
24
+ // untrusted target arguments are forwarded exclusively through quoted "$@".
25
+ export const LINUX_BWRAP_DESCRIPTOR_SCRUBBER_SCRIPT = [
26
+ "set -u",
27
+ "shopt -s execfail",
28
+ 'chainless_preserved_max_fd="$1"',
29
+ 'chainless_executable_fd="$2"',
30
+ "shift 2",
31
+ 'case "$chainless_preserved_max_fd" in',
32
+ ` ""|*[!0-9]*) exit ${LINUX_BWRAP_DESCRIPTOR_SCRUBBER_FAILURE_STATUS} ;;`,
33
+ "esac",
34
+ 'case "$chainless_executable_fd" in',
35
+ ` ""|*[!0-9]*) exit ${LINUX_BWRAP_DESCRIPTOR_SCRUBBER_FAILURE_STATUS} ;;`,
36
+ "esac",
37
+ "if [[ ! $chainless_preserved_max_fd =~ ^[1-9][0-9]*$ ||",
38
+ " ! $chainless_executable_fd =~ ^[1-9][0-9]*$ ||",
39
+ " ${#chainless_preserved_max_fd} -gt 10 ||",
40
+ " ${#chainless_executable_fd} -gt 10 ]]; then",
41
+ ` exit ${LINUX_BWRAP_DESCRIPTOR_SCRUBBER_FAILURE_STATUS}`,
42
+ "fi",
43
+ "if (( chainless_preserved_max_fd < 3 ||",
44
+ " chainless_preserved_max_fd > 2147483647 ||",
45
+ " chainless_executable_fd < 3 ||",
46
+ " chainless_executable_fd > 2147483647 ||",
47
+ " chainless_executable_fd > chainless_preserved_max_fd )); then",
48
+ ` exit ${LINUX_BWRAP_DESCRIPTOR_SCRUBBER_FAILURE_STATUS}`,
49
+ "fi",
50
+ "chainless_sweep_fds() {",
51
+ " local chainless_fd_path chainless_fd",
52
+ " chainless_sweep_found=0",
53
+ " chainless_sweep_seen_executable=0",
54
+ " for chainless_fd_path in /proc/self/fd/*; do",
55
+ // Bash's glob enumeration can briefly contribute its own now-stale procfs
56
+ // entry. -L is a Bash builtin and distinguishes that closed entry without
57
+ // opening another descriptor or following the descriptor's target.
58
+ ' [[ -L "$chainless_fd_path" ]] || continue',
59
+ ' chainless_fd="${chainless_fd_path##*/}"',
60
+ ' case "$chainless_fd" in',
61
+ ` ""|*[!0-9]*) exit ${LINUX_BWRAP_DESCRIPTOR_SCRUBBER_FAILURE_STATUS} ;;`,
62
+ " esac",
63
+ " if (( chainless_fd == chainless_executable_fd )); then",
64
+ " chainless_sweep_seen_executable=1",
65
+ " fi",
66
+ " if (( chainless_fd > chainless_preserved_max_fd )); then",
67
+ " chainless_sweep_found=1",
68
+ // Bash's variable-fd close form handles descriptors above 9 without eval.
69
+ ` exec {chainless_fd}>&- || exit ${LINUX_BWRAP_DESCRIPTOR_SCRUBBER_FAILURE_STATUS}`,
70
+ " fi",
71
+ " done",
72
+ " if (( chainless_sweep_seen_executable != 1 )); then",
73
+ ` return ${LINUX_BWRAP_DESCRIPTOR_SCRUBBER_FAILURE_STATUS}`,
74
+ " fi",
75
+ "}",
76
+ `chainless_sweep_fds || exit ${LINUX_BWRAP_DESCRIPTOR_SCRUBBER_FAILURE_STATUS}`,
77
+ `chainless_sweep_fds || exit ${LINUX_BWRAP_DESCRIPTOR_SCRUBBER_FAILURE_STATUS}`,
78
+ 'chainless_second_sweep_found="$chainless_sweep_found"',
79
+ `chainless_sweep_fds || exit ${LINUX_BWRAP_DESCRIPTOR_SCRUBBER_FAILURE_STATUS}`,
80
+ 'chainless_third_sweep_found="$chainless_sweep_found"',
81
+ "if (( chainless_second_sweep_found != 0 ||",
82
+ " chainless_third_sweep_found != 0 )); then",
83
+ ` exit ${LINUX_BWRAP_DESCRIPTOR_SCRUBBER_FAILURE_STATUS}`,
84
+ "fi",
85
+ 'exec /proc/self/fd/"$chainless_executable_fd" "$@"',
86
+ `exit ${LINUX_BWRAP_DESCRIPTOR_SCRUBBER_FAILURE_STATUS}`,
87
+ ].join("\n");
88
+
89
+ export const LINUX_BWRAP_DESCRIPTOR_SCRUBBER_SCRIPT_SHA256 = crypto
90
+ .createHash("sha256")
91
+ .update(LINUX_BWRAP_DESCRIPTOR_SCRUBBER_SCRIPT)
92
+ .digest("hex");
93
+
94
+ const FIXED_PREFIX = Object.freeze([
95
+ "--noprofile",
96
+ "--norc",
97
+ "-c",
98
+ LINUX_BWRAP_DESCRIPTOR_SCRUBBER_SCRIPT,
99
+ LINUX_BWRAP_DESCRIPTOR_SCRUBBER_ARGV0,
100
+ ]);
101
+
102
+ function childFd(value) {
103
+ return Number.isSafeInteger(value) && value >= 3 ? value : null;
104
+ }
105
+
106
+ function denseDataArraySnapshot(value) {
107
+ if (
108
+ !Array.isArray(value) ||
109
+ Object.getPrototypeOf(value) !== Array.prototype
110
+ ) {
111
+ return null;
112
+ }
113
+ const descriptors = Object.getOwnPropertyDescriptors(value);
114
+ const lengthDescriptor = descriptors.length;
115
+ if (
116
+ !lengthDescriptor ||
117
+ !("value" in lengthDescriptor) ||
118
+ !Number.isSafeInteger(lengthDescriptor.value) ||
119
+ lengthDescriptor.value < 0 ||
120
+ Reflect.ownKeys(descriptors).length !== lengthDescriptor.value + 1
121
+ ) {
122
+ return null;
123
+ }
124
+ const snapshot = [];
125
+ for (let index = 0; index < lengthDescriptor.value; index += 1) {
126
+ const descriptor = descriptors[String(index)];
127
+ if (!descriptor || !("value" in descriptor)) {
128
+ return null;
129
+ }
130
+ snapshot.push(descriptor.value);
131
+ }
132
+ return Object.freeze(snapshot);
133
+ }
134
+
135
+ function ownDataDescriptorSnapshot(value) {
136
+ if (
137
+ !value ||
138
+ typeof value !== "object" ||
139
+ Array.isArray(value) ||
140
+ Object.getPrototypeOf(value) !== Object.prototype
141
+ ) {
142
+ return null;
143
+ }
144
+ const descriptors = Object.getOwnPropertyDescriptors(value);
145
+ for (const key of Reflect.ownKeys(descriptors)) {
146
+ if (typeof key !== "string" || !("value" in descriptors[key])) {
147
+ return null;
148
+ }
149
+ }
150
+ return descriptors;
151
+ }
152
+
153
+ function fixedEnvironmentSnapshot(value) {
154
+ const descriptors = ownDataDescriptorSnapshot(value);
155
+ if (
156
+ !descriptors ||
157
+ Reflect.ownKeys(descriptors).length !== 3 ||
158
+ descriptors.PATH?.value !== "/usr/bin:/bin" ||
159
+ descriptors.LANG?.value !== "C" ||
160
+ descriptors.LC_ALL?.value !== "C"
161
+ ) {
162
+ return null;
163
+ }
164
+ return Object.freeze({
165
+ PATH: descriptors.PATH.value,
166
+ LANG: descriptors.LANG.value,
167
+ LC_ALL: descriptors.LC_ALL.value,
168
+ });
169
+ }
170
+
171
+ /** Build the exact Bash argv wrapper around a descriptor-backed executable. */
172
+ export function buildLinuxBwrapDescriptorScrubbedLaunch({
173
+ scrubberChildFd,
174
+ preservedMaxFd,
175
+ executableChildFd,
176
+ executableArgs,
177
+ }) {
178
+ const executableArgsSnapshot = denseDataArraySnapshot(executableArgs);
179
+ if (
180
+ childFd(scrubberChildFd) === null ||
181
+ childFd(preservedMaxFd) === null ||
182
+ childFd(executableChildFd) === null ||
183
+ scrubberChildFd !== preservedMaxFd + 1 ||
184
+ executableChildFd > preservedMaxFd ||
185
+ !executableArgsSnapshot ||
186
+ !executableArgsSnapshot.every((value) => typeof value === "string")
187
+ ) {
188
+ throw new Error("linux_bwrap_descriptor_scrubber_layout_invalid");
189
+ }
190
+ return Object.freeze({
191
+ command: `/proc/self/fd/${scrubberChildFd}`,
192
+ args: Object.freeze([
193
+ ...FIXED_PREFIX,
194
+ String(preservedMaxFd),
195
+ String(executableChildFd),
196
+ ...executableArgsSnapshot,
197
+ ]),
198
+ });
199
+ }
200
+
201
+ /**
202
+ * Parse only the current exact wrapper grammar. Direct legacy fd launches,
203
+ * altered scripts/options, sparse layouts, and non-numeric fd arguments fail.
204
+ */
205
+ export function parseLinuxBwrapDescriptorScrubbedLaunch(
206
+ command,
207
+ args,
208
+ options,
209
+ { activeStdioThrough = 2 } = {},
210
+ ) {
211
+ const argsSnapshot = denseDataArraySnapshot(args);
212
+ const optionDescriptors = ownDataDescriptorSnapshot(options);
213
+ const stdio = denseDataArraySnapshot(optionDescriptors?.stdio?.value);
214
+ const callerEnvironment = fixedEnvironmentSnapshot(
215
+ optionDescriptors?.env?.value,
216
+ );
217
+ if (
218
+ !argsSnapshot ||
219
+ !optionDescriptors ||
220
+ optionDescriptors.shell?.value !== false ||
221
+ (optionDescriptors.serialization &&
222
+ optionDescriptors.serialization.value !== undefined) ||
223
+ !stdio ||
224
+ stdio.length < 5 ||
225
+ !callerEnvironment
226
+ ) {
227
+ return null;
228
+ }
229
+ const optionsSnapshot = {};
230
+ for (const key of Reflect.ownKeys(optionDescriptors)) {
231
+ if (key === "stdio" || key === "env" || key === "shell") continue;
232
+ Object.defineProperty(optionsSnapshot, key, {
233
+ value: optionDescriptors[key].value,
234
+ enumerable: true,
235
+ configurable: true,
236
+ writable: true,
237
+ });
238
+ }
239
+ Object.defineProperties(optionsSnapshot, {
240
+ shell: {
241
+ value: false,
242
+ enumerable: true,
243
+ configurable: true,
244
+ writable: true,
245
+ },
246
+ stdio: {
247
+ value: stdio,
248
+ enumerable: true,
249
+ configurable: true,
250
+ writable: true,
251
+ },
252
+ env: {
253
+ value: callerEnvironment,
254
+ enumerable: true,
255
+ configurable: true,
256
+ writable: true,
257
+ },
258
+ });
259
+ const scrubberChildFd = stdio.length - 1;
260
+ const preservedMaxFd = scrubberChildFd - 1;
261
+ if (
262
+ !Number.isSafeInteger(activeStdioThrough) ||
263
+ activeStdioThrough < 2 ||
264
+ activeStdioThrough > preservedMaxFd
265
+ ) {
266
+ return null;
267
+ }
268
+ if (
269
+ command !== `/proc/self/fd/${scrubberChildFd}` ||
270
+ !Number.isInteger(stdio[scrubberChildFd]) ||
271
+ argsSnapshot.length < FIXED_PREFIX.length + 2 ||
272
+ !FIXED_PREFIX.every((value, index) => argsSnapshot[index] === value) ||
273
+ argsSnapshot[FIXED_PREFIX.length] !== String(preservedMaxFd) ||
274
+ !/^[1-9]\d*$/.test(argsSnapshot[FIXED_PREFIX.length + 1] || "")
275
+ ) {
276
+ return null;
277
+ }
278
+ const parentFds = new Set();
279
+ let nodeIpcChildFd = null;
280
+ for (let index = 3; index <= scrubberChildFd; index += 1) {
281
+ if (!Object.hasOwn(stdio, index)) {
282
+ return null;
283
+ }
284
+ const value = stdio[index];
285
+ if (index <= activeStdioThrough) {
286
+ if (value !== "pipe" && value !== "ipc") {
287
+ return null;
288
+ }
289
+ if (value === "ipc") {
290
+ if (nodeIpcChildFd !== null) return null;
291
+ nodeIpcChildFd = index;
292
+ }
293
+ continue;
294
+ }
295
+ if (!Number.isSafeInteger(value) || value < 0 || parentFds.has(value)) {
296
+ return null;
297
+ }
298
+ parentFds.add(value);
299
+ }
300
+ const executableChildFd = Number(argsSnapshot[FIXED_PREFIX.length + 1]);
301
+ if (
302
+ !Number.isSafeInteger(executableChildFd) ||
303
+ String(executableChildFd) !== argsSnapshot[FIXED_PREFIX.length + 1] ||
304
+ executableChildFd < 3 ||
305
+ executableChildFd > preservedMaxFd ||
306
+ !Number.isInteger(stdio[executableChildFd])
307
+ ) {
308
+ return null;
309
+ }
310
+ const executableArgs = Object.freeze([
311
+ ...argsSnapshot.slice(FIXED_PREFIX.length + 2),
312
+ ]);
313
+ if (!executableArgs.every((value) => typeof value === "string")) {
314
+ return null;
315
+ }
316
+ return Object.freeze({
317
+ scrubberChildFd,
318
+ preservedMaxFd,
319
+ activeStdioThrough,
320
+ nodeIpcChildFd,
321
+ executableChildFd,
322
+ executableArgs,
323
+ launchArgs: argsSnapshot,
324
+ options: Object.freeze(optionsSnapshot),
325
+ stdio,
326
+ callerEnvironment,
327
+ shell: false,
328
+ serialization: undefined,
329
+ });
330
+ }
331
+
332
+ export function linuxBwrapDescriptorScrubberPolicyBinding(
333
+ executableIdentity,
334
+ layout,
335
+ ) {
336
+ const identitySnapshot = Object.freeze({
337
+ path: executableIdentity?.path,
338
+ fileId: Object.freeze({
339
+ dev: String(executableIdentity?.fileId?.dev),
340
+ ino: String(executableIdentity?.fileId?.ino),
341
+ }),
342
+ sha256: executableIdentity?.sha256,
343
+ bytes: executableIdentity?.bytes,
344
+ mtimeMs: executableIdentity?.mtimeMs,
345
+ mode: executableIdentity?.mode,
346
+ uid: executableIdentity?.uid,
347
+ gid: executableIdentity?.gid,
348
+ });
349
+ return Object.freeze({
350
+ kind: LINUX_BWRAP_DESCRIPTOR_SCRUBBER_KIND,
351
+ mechanism: LINUX_BWRAP_DESCRIPTOR_SCRUBBER_MECHANISM,
352
+ scriptSha256: LINUX_BWRAP_DESCRIPTOR_SCRUBBER_SCRIPT_SHA256,
353
+ executableIdentity: identitySnapshot,
354
+ executablePinned: true,
355
+ argvFixed: true,
356
+ callerEnvironmentFixed: true,
357
+ nodeRuntimeEnvironmentInjection:
358
+ layout.nodeIpcChildFd === null || layout.nodeIpcChildFd === undefined
359
+ ? "none"
360
+ : "node-child-process-exact-ipc-v1",
361
+ nodeIpcChildFd: layout.nodeIpcChildFd ?? null,
362
+ nodeIpcSerializationMode:
363
+ layout.nodeIpcChildFd === null || layout.nodeIpcChildFd === undefined
364
+ ? null
365
+ : "json",
366
+ procSelfFdPasses: LINUX_BWRAP_DESCRIPTOR_SCRUBBER_PASSES,
367
+ closesUnknownInheritedDescriptors: true,
368
+ verificationPassesFailClosed: true,
369
+ policyBound: true,
370
+ scrubberChildFd: layout.scrubberChildFd,
371
+ preservedMaxFd: layout.preservedMaxFd,
372
+ activeStdioThrough: layout.activeStdioThrough ?? 2,
373
+ executableChildFd: layout.executableChildFd,
374
+ });
375
+ }
@@ -17,6 +17,10 @@ import {
17
17
  LINUX_GENERIC_PTY_LAUNCHER_PATH,
18
18
  planLinuxGenericBubblewrap,
19
19
  } from "./linux-generic-bwrap.js";
20
+ import {
21
+ buildLinuxBwrapDescriptorScrubbedLaunch,
22
+ LINUX_BWRAP_DESCRIPTOR_SCRUBBER_PATH,
23
+ } from "./linux-bwrap-descriptor-launch.js";
20
24
 
21
25
  const BWRAP_PATH = "/usr/bin/bwrap";
22
26
  const MAX_ATTESTED_FILE_BYTES = 256 * 1024 * 1024;
@@ -831,6 +835,71 @@ function createTrustedResources(
831
835
  bytes: supervisorBytes,
832
836
  });
833
837
 
838
+ const descriptorScrubber = openPair(LINUX_BWRAP_DESCRIPTOR_SCRUBBER_PATH, {
839
+ directory: false,
840
+ rootRequired: true,
841
+ executable: true,
842
+ });
843
+ const descriptorScrubberStat = runtime.fs.fstatSync(
844
+ descriptorScrubber.finalFd,
845
+ );
846
+ const descriptorScrubberBytes = Number(descriptorScrubberStat.size);
847
+ const descriptorScrubberProbeDigest = hashOpenFile(
848
+ runtime,
849
+ descriptorScrubber.probeFd,
850
+ descriptorScrubberBytes,
851
+ );
852
+ const descriptorScrubberFinalDigest = hashOpenFile(
853
+ runtime,
854
+ descriptorScrubber.finalFd,
855
+ descriptorScrubberBytes,
856
+ );
857
+ if (descriptorScrubberProbeDigest !== descriptorScrubberFinalDigest) {
858
+ throw new Error("descriptor_scrubber_digest_mismatch");
859
+ }
860
+ descriptorScrubber.identity = Object.freeze({
861
+ ...descriptorScrubber.identity,
862
+ sha256: descriptorScrubberFinalDigest,
863
+ bytes: descriptorScrubberBytes,
864
+ mtimeMs: Number(descriptorScrubberStat.mtimeMs),
865
+ });
866
+
867
+ const spawnScrubbedCapability = (executableFd, executableArgs) => {
868
+ const scrubberFd = runtime.fs.openSync(
869
+ LINUX_BWRAP_DESCRIPTOR_SCRUBBER_PATH,
870
+ openFlags({ directory: false }),
871
+ );
872
+ ownedFds.add(scrubberFd);
873
+ try {
874
+ const scrubberStat = runtime.fs.fstatSync(scrubberFd);
875
+ if (
876
+ !statMatchesIdentity(scrubberStat, descriptorScrubber.identity, {
877
+ directory: false,
878
+ }) ||
879
+ hashOpenFile(runtime, scrubberFd, descriptorScrubberBytes) !==
880
+ descriptorScrubberFinalDigest
881
+ ) {
882
+ throw new Error("descriptor_scrubber_capability_reader_unattested");
883
+ }
884
+ const stdio = ["ignore", "pipe", "pipe", executableFd, scrubberFd];
885
+ const launch = buildLinuxBwrapDescriptorScrubbedLaunch({
886
+ scrubberChildFd: 4,
887
+ preservedMaxFd: 3,
888
+ executableChildFd: 3,
889
+ executableArgs,
890
+ });
891
+ return runtime.spawnSync(launch.command, launch.args, {
892
+ shell: false,
893
+ encoding: "utf8",
894
+ stdio,
895
+ timeout: 10_000,
896
+ env: { PATH: "/usr/bin:/bin", LANG: "C", LC_ALL: "C" },
897
+ });
898
+ } finally {
899
+ closeFd(scrubberFd);
900
+ }
901
+ };
902
+
834
903
  const capabilityFd = runtime.fs.openSync(
835
904
  BWRAP_PATH,
836
905
  openFlags({ directory: false }),
@@ -846,13 +915,7 @@ function createTrustedResources(
846
915
  ) {
847
916
  throw new Error("bubblewrap_capability_reader_unattested");
848
917
  }
849
- const capabilityResult = runtime.spawnSync("/proc/self/fd/3", ["--help"], {
850
- shell: false,
851
- encoding: "utf8",
852
- stdio: ["ignore", "pipe", "pipe", capabilityFd],
853
- timeout: 10_000,
854
- env: { PATH: "/usr/bin:/bin", LANG: "C", LC_ALL: "C" },
855
- });
918
+ const capabilityResult = spawnScrubbedCapability(capabilityFd, ["--help"]);
856
919
  closeFd(capabilityFd);
857
920
  if (capabilityResult?.error || capabilityResult?.status !== 0) {
858
921
  const error = new Error("bubblewrap_capability_probe_failed");
@@ -916,16 +979,9 @@ function createTrustedResources(
916
979
  ) {
917
980
  throw new Error("pty_launcher_capability_reader_unattested");
918
981
  }
919
- const launcherCapabilityResult = runtime.spawnSync(
920
- "/proc/self/fd/3",
982
+ const launcherCapabilityResult = spawnScrubbedCapability(
983
+ launcherCapabilityFd,
921
984
  ["--help"],
922
- {
923
- shell: false,
924
- encoding: "utf8",
925
- stdio: ["ignore", "pipe", "pipe", launcherCapabilityFd],
926
- timeout: 10_000,
927
- env: { PATH: "/usr/bin:/bin", LANG: "C", LC_ALL: "C" },
928
- },
929
985
  );
930
986
  closeFd(launcherCapabilityFd);
931
987
  const launcherHelp =
@@ -1201,6 +1257,16 @@ function createTrustedResources(
1201
1257
  !descriptorAttested(supervisor.finalFd, supervisor.identity, false) ||
1202
1258
  hashOpenFile(runtime, supervisor.finalFd, supervisorBytes) !==
1203
1259
  supervisorFinalDigest ||
1260
+ !descriptorAttested(
1261
+ descriptorScrubber.finalFd,
1262
+ descriptorScrubber.identity,
1263
+ false,
1264
+ ) ||
1265
+ hashOpenFile(
1266
+ runtime,
1267
+ descriptorScrubber.finalFd,
1268
+ descriptorScrubberBytes,
1269
+ ) !== descriptorScrubberFinalDigest ||
1204
1270
  (sandboxOpts?.pty === true &&
1205
1271
  (!descriptorAttested(
1206
1272
  ptyLauncher?.finalFd,
@@ -1474,6 +1540,14 @@ function createTrustedResources(
1474
1540
  sha256: supervisorFinalDigest,
1475
1541
  bytes: supervisorBytes,
1476
1542
  },
1543
+ descriptorScrubber: {
1544
+ probeFd: descriptorScrubber.probeFd,
1545
+ finalFd: descriptorScrubber.finalFd,
1546
+ identity: descriptorScrubber.identity,
1547
+ sha256: descriptorScrubberFinalDigest,
1548
+ bytes: descriptorScrubberBytes,
1549
+ mtimeMs: Number(descriptorScrubberStat.mtimeMs),
1550
+ },
1477
1551
  ...(ptyLauncher
1478
1552
  ? {
1479
1553
  ptyLauncher: {