chainlesschain 0.162.176 → 0.162.178

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 (260) hide show
  1. package/README.md +10 -0
  2. package/package.json +1 -1
  3. package/src/assets/web-panel/.build-hash +1 -1
  4. package/src/assets/web-panel/assets/{AIOps-BDLu5Elz.js → AIOps-DRftcSue.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-DH5us-CK.js → ActionButton-BFvUaMKR.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-BZ0u8IFG.js → Analytics-C0-Rru4P.js} +3 -3
  7. package/src/assets/web-panel/assets/AppLayout-bx-BCljj.js +9 -0
  8. package/src/assets/web-panel/assets/{Artifacts-Br2YBbh_.js → Artifacts-DAJ8B3Un.js} +1 -1
  9. package/src/assets/web-panel/assets/{Audit-C3C6a482.js → Audit-hOk4L1lr.js} +1 -1
  10. package/src/assets/web-panel/assets/{BackgroundAgents-CzHvebcj.js → BackgroundAgents-3pbDpM9z.js} +1 -1
  11. package/src/assets/web-panel/assets/{Backup-DZNHYDFd.js → Backup-BtziGDn9.js} +1 -1
  12. package/src/assets/web-panel/assets/{BaseInput-VRiC4fIx.js → BaseInput-kmshphJ3.js} +1 -1
  13. package/src/assets/web-panel/assets/{Chat-Cm08WWAD.js → Chat-d7tGSosA.js} +5 -5
  14. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CGHYrugQ.js → ChatBubbleRenderer-p-_PBpX_.js} +1 -1
  15. package/src/assets/web-panel/assets/{Checkbox-DtByk7d7.js → Checkbox-C4Eh4Tz5.js} +1 -1
  16. package/src/assets/web-panel/assets/{Codegen-CphXXOfD.js → Codegen-r7gmhZyA.js} +1 -1
  17. package/src/assets/web-panel/assets/{Col-Hz86TnLR.js → Col-U7mDaGlL.js} +1 -1
  18. package/src/assets/web-panel/assets/{Community-HP03ltpD.js → Community-Bpu8aH1T.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compact-B_N1mqQz.js → Compact-CHb2XBJe.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compliance-CVztRpi8.js → Compliance-Cn_r4dey.js} +1 -1
  21. package/src/assets/web-panel/assets/{Cowork-wUVOyZih.js → Cowork-CdMWfDcz.js} +4 -4
  22. package/src/assets/web-panel/assets/{Cron-DW5TLJKw.js → Cron-BtnREHWy.js} +2 -2
  23. package/src/assets/web-panel/assets/{Crosschain-CrAFGhWH.js → Crosschain-BKI9TSzr.js} +1 -1
  24. package/src/assets/web-panel/assets/{DID-pA-oD8ke.js → DID-pkNubzzJ.js} +2 -2
  25. package/src/assets/web-panel/assets/Dashboard-1rrz1snN.js +3 -0
  26. package/src/assets/web-panel/assets/{Dropdown-EweJcsek.js → Dropdown-DLyFVxDc.js} +1 -1
  27. package/src/assets/web-panel/assets/{EmailListRenderer-C9xVLPG4.js → EmailListRenderer-CtUWfYVq.js} +1 -1
  28. package/src/assets/web-panel/assets/{FamilyGuardDashboard-CDcEEqlu.js → FamilyGuardDashboard-B8eX2Qe4.js} +1 -1
  29. package/src/assets/web-panel/assets/{Federation-DtZda9A_.js → Federation-D8lsDGus.js} +1 -1
  30. package/src/assets/web-panel/assets/{FormItemContext-CiYdcVz3.js → FormItemContext-CRYt_aIw.js} +1 -1
  31. package/src/assets/web-panel/assets/{GenericCardRenderer-DA13uwA0.js → GenericCardRenderer-ClKzY8_N.js} +1 -1
  32. package/src/assets/web-panel/assets/{Git-DzRhZD1O.js → Git-BXj5Dney.js} +2 -2
  33. package/src/assets/web-panel/assets/{Governance-D5RMgOSb.js → Governance-Cm-I8RMz.js} +1 -1
  34. package/src/assets/web-panel/assets/{Inference-BgrPfSNk.js → Inference-CPvbhvgt.js} +1 -1
  35. package/src/assets/web-panel/assets/{KnowledgeGraph-DzjnD571.js → KnowledgeGraph-sYNDZaoi.js} +1 -1
  36. package/src/assets/web-panel/assets/{Logs-BhWzVDtN.js → Logs-BZY_3CRZ.js} +2 -2
  37. package/src/assets/web-panel/assets/{MarkdownRenderer-BDape9cx.js → MarkdownRenderer-up0BW6pv.js} +1 -1
  38. package/src/assets/web-panel/assets/{Marketplace-DJtL5GV7.js → Marketplace-C5MEJ2Qe.js} +1 -1
  39. package/src/assets/web-panel/assets/{McpTools-CZcQygI7.js → McpTools-ihdrn43I.js} +5 -5
  40. package/src/assets/web-panel/assets/{Memory-DUWSDUUu.js → Memory-Br8bPMlh.js} +2 -2
  41. package/src/assets/web-panel/assets/{MobileBridge-BTwq2WKY.js → MobileBridge-BNntgrYW.js} +1 -1
  42. package/src/assets/web-panel/assets/MobileProjects-BdV915mw.js +1 -0
  43. package/src/assets/web-panel/assets/{Mtc-BiGugEQm.js → Mtc-A3wDmlqL.js} +5 -5
  44. package/src/assets/web-panel/assets/{MtcAudit-DY7a6gUe.js → MtcAudit-CF-mBLWM.js} +2 -2
  45. package/src/assets/web-panel/assets/{Multisig-BQbDu_w7.js → Multisig-Iy2k_MSo.js} +3 -3
  46. package/src/assets/web-panel/assets/{NLProgramming-CM2wXTLv.js → NLProgramming-kk0W7HUb.js} +1 -1
  47. package/src/assets/web-panel/assets/{Notes-DI6gGs1v.js → Notes-B5u5t_4S.js} +3 -3
  48. package/src/assets/web-panel/assets/{NotificationSettings-BsZOLWAB.js → NotificationSettings-BN0POf6_.js} +1 -1
  49. package/src/assets/web-panel/assets/OrderTableRenderer-CHkSUrXB.js +1 -0
  50. package/src/assets/web-panel/assets/{Organization-Cds0_tXr.js → Organization-DwWQESuN.js} +4 -4
  51. package/src/assets/web-panel/assets/{Overflow-WunYMD87.js → Overflow-DG6klrcC.js} +1 -1
  52. package/src/assets/web-panel/assets/{P2P-Bo6j4DDv.js → P2P-BwJcKkgZ.js} +2 -2
  53. package/src/assets/web-panel/assets/{PdhVaultBrowser-Bh2XPD5f.js → PdhVaultBrowser-BwOHG0in.js} +5 -5
  54. package/src/assets/web-panel/assets/{Permissions-EMvMMC8N.js → Permissions-CGMXe4TX.js} +4 -4
  55. package/src/assets/web-panel/assets/PersonalDataHub-ziYqg7-A.js +8 -0
  56. package/src/assets/web-panel/assets/{Pipeline-BOx8HOgL.js → Pipeline-BzJfeoGt.js} +1 -1
  57. package/src/assets/web-panel/assets/{Privacy-tBeTVQVM.js → Privacy-DLh3Bblx.js} +1 -1
  58. package/src/assets/web-panel/assets/{ProjectInit-CVYg1W4M.js → ProjectInit-USVWW36c.js} +2 -2
  59. package/src/assets/web-panel/assets/{ProjectSettings-Dvt5I7y1.js → ProjectSettings-CiiOn62h.js} +2 -2
  60. package/src/assets/web-panel/assets/Projects-6V-PNmcA.js +1 -0
  61. package/src/assets/web-panel/assets/{Providers-Ct8xqY-E.js → Providers-CBPWWzpu.js} +1 -1
  62. package/src/assets/web-panel/assets/{QrScannerModal-Cni8Ooja.js → QrScannerModal-QVwoRUq3.js} +1 -1
  63. package/src/assets/web-panel/assets/{QuickAsk-BJVLKdxr.js → QuickAsk-CXnR-2Vn.js} +1 -1
  64. package/src/assets/web-panel/assets/{Recommend-DPG8Rbbm.js → Recommend-ClaNzjmF.js} +1 -1
  65. package/src/assets/web-panel/assets/{RemoteSession-DsdR7dCt.js → RemoteSession-C3rGw8vJ.js} +2 -2
  66. package/src/assets/web-panel/assets/{Reputation-Csg1YM-b.js → Reputation-Ci-OWAoP.js} +1 -1
  67. package/src/assets/web-panel/assets/{Row-D9DoFoEf.js → Row-DRhAwXOS.js} +1 -1
  68. package/src/assets/web-panel/assets/{RssFeed-BsvKrXMS.js → RssFeed-BQLJQ2_y.js} +3 -3
  69. package/src/assets/web-panel/assets/{Search-DFUStfgQ.js → Search-QQUpkfFd.js} +1 -1
  70. package/src/assets/web-panel/assets/{Security-ILg1zxdK.js → Security-DdXKzuKT.js} +4 -4
  71. package/src/assets/web-panel/assets/{Services-Dd41PCaY.js → Services-x2Zh62Qd.js} +2 -2
  72. package/src/assets/web-panel/assets/{Skeleton-Bzo1cN80.js → Skeleton-GdY4KwRz.js} +1 -1
  73. package/src/assets/web-panel/assets/{Skills-BDHh17P0.js → Skills-Bv4tY1Fd.js} +1 -1
  74. package/src/assets/web-panel/assets/{Sla-jl7UTiRY.js → Sla-C3QnM-11.js} +1 -1
  75. package/src/assets/web-panel/assets/{SpeechSettings-BePa-RF6.js → SpeechSettings-Bl3ytvmI.js} +1 -1
  76. package/src/assets/web-panel/assets/{SyncSettings-DiqqDKGZ.js → SyncSettings-Wp9IwTsP.js} +2 -2
  77. package/src/assets/web-panel/assets/{Tasks-DYQ_6lxj.js → Tasks-CF3rIrDe.js} +1 -1
  78. package/src/assets/web-panel/assets/{Templates-JiDeI06L.js → Templates-CGfvVVM9.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tenant-hhgI6zwS.js → Tenant-CVXmwQ3U.js} +1 -1
  80. package/src/assets/web-panel/assets/Terminal-bvwrt03E.js +3 -0
  81. package/src/assets/web-panel/assets/{TimelineRenderer-B8uB5Llk.js → TimelineRenderer-D0g74KhH.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tokens-C3b_6r2z.js → Tokens-BH4IwzlT.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trigger-tIP7HKVe.js → Trigger-DJOpM533.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trust-vjoc11vJ.js → Trust-B43EPRLr.js} +1 -1
  85. package/src/assets/web-panel/assets/{UkeySign-DUPBnGuH.js → UkeySign-BmBFG-em.js} +1 -1
  86. package/src/assets/web-panel/assets/{VideoEditing-CBvhUY5T.js → VideoEditing-n9oJwB8k.js} +1 -1
  87. package/src/assets/web-panel/assets/{Wallet-DUaQ0uA5.js → Wallet-D5QeivHp.js} +4 -4
  88. package/src/assets/web-panel/assets/{WebAuthn-DllSivjE.js → WebAuthn-DcNy7igO.js} +5 -5
  89. package/src/assets/web-panel/assets/{WorkflowEditor-xc8D3uO6.js → WorkflowEditor-BVjc7-5-.js} +1 -1
  90. package/src/assets/web-panel/assets/{chat-BVicU7oA.js → chat-Dy5Tfj3m.js} +1 -1
  91. package/src/assets/web-panel/assets/{colors-DJzLmhLm.js → colors-C4c2CNZU.js} +1 -1
  92. package/src/assets/web-panel/assets/{compact-item-BvYRfThE.js → compact-item-DPa3O5vN.js} +1 -1
  93. package/src/assets/web-panel/assets/{createContext-DGXxCBKR.js → createContext-TLcfNA6_.js} +1 -1
  94. package/src/assets/web-panel/assets/devWarning-BAwdDA_5.js +1 -0
  95. package/src/assets/web-panel/assets/{hasIn-SBDJB1y4.js → hasIn-D41LVFkp.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-D7HimK0M.js → index-0oevYjfT.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DCdRAgjy.js → index-388pLGJ1.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BO1itZaY.js → index-B8nLBZbv.js} +3 -3
  99. package/src/assets/web-panel/assets/{index-DvUTDYXX.js → index-BPTGAjee.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-hxTODbM1.js → index-BPtrOBmW.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-wcCL-miV.js → index-BQiIxHBy.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CKyEivf8.js → index-BSM1cHVK.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BJZf9DhV.js → index-BYPr9fkz.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-DHVLJ8q0.js → index-BsQ7Ev6i.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-Cs2rmLFt.js → index-Btk9qLL2.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-z1ZylsLq.js → index-BvmziZSG.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-Cf-O_g_8.js → index-BvopLC_T.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DMarmfrv.js → index-C7xhTVyP.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-CoJAO1Lm.js → index-CNk_ZooP.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-9gdI7uUW.js → index-CQrEHoOG.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Bf-ctERC.js → index-CSxex23J.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-MjC4G09d.js → index-CVjgm992.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-e4fXH_WO.js → index-CWK4zOPe.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-xfluRkCT.js → index-CX0VsoP4.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DRfiXB_p.js → index-CXl0YPNG.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-d5BVd-cL.js → index-Cip7LWml.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-Dm_77jgR.js → index-Cq_hlWNt.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-YJkzy8ZF.js → index-CzZ49YZL.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-CtwqO5qo.js → index-D2Nkivlm.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BYqz4Wrr.js → index-DBUgRs4D.js} +1 -1
  121. package/src/assets/web-panel/assets/index-DEjVkdzq.js +1 -0
  122. package/src/assets/web-panel/assets/{index-CdGY9P8a.js → index-DNsBj2Ob.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DonCnfMr.js → index-Di4X8cfI.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-1SdDS6lR.js → index-DljFsVGI.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DnjPdvR6.js → index-Korc3QIe.js} +1 -1
  126. package/src/assets/web-panel/assets/index-LMOc5xrS.js +1 -0
  127. package/src/assets/web-panel/assets/{index-VMfwIH5G.js → index-MKZDje0H.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-DKrvvWm4.js → index-OHAfRu_3.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-FxZzRyE1.js → index-WEJr8PL5.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-Crk5NTb0.js → index-WinCp6du.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DCqRS6da.js → index-Yjr6cqSK.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-BTrBGBJs.js → index-iQ6gtFih.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-lpaGoTH3.js → index-pt3s7yvV.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-CloCgBUR.js → index-tQ3igERQ.js} +1 -1
  135. package/src/assets/web-panel/assets/{initDefaultProps-C1zO1KnY.js → initDefaultProps-BFZu87WZ.js} +1 -1
  136. package/src/assets/web-panel/assets/{motion-CWLtEGmC.js → motion-DJIo7qvt.js} +1 -1
  137. package/src/assets/web-panel/assets/{move-DzD_C3Vm.js → move-Cfr5qknL.js} +1 -1
  138. package/src/assets/web-panel/assets/{mtc-parser-D880PYJl.js → mtc-parser-Bgc-OadH.js} +1 -1
  139. package/src/assets/web-panel/assets/{omit-CFR_z2ov.js → omit-X3WI-TNp.js} +1 -1
  140. package/src/assets/web-panel/assets/{pickAttrs-srIhgrSC.js → pickAttrs-pJhU9IxK.js} +1 -1
  141. package/src/assets/web-panel/assets/{placementArrow-C1rXpibP.js → placementArrow-BNg_Vj3T.js} +1 -1
  142. package/src/assets/web-panel/assets/{responsiveObserve-C30gRcSS.js → responsiveObserve-TeSEGQ5-.js} +1 -1
  143. package/src/assets/web-panel/assets/{slide-CvtKiMfV.js → slide-D_t_P0bv.js} +1 -1
  144. package/src/assets/web-panel/assets/{statusUtils-DNHO7ITG.js → statusUtils-DrrIMwAT.js} +1 -1
  145. package/src/assets/web-panel/assets/{styleChecker-Dt_Sl-g4.js → styleChecker-BjZCuFRm.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFlexGapSupport-Cjev42Gh.js → useFlexGapSupport-rTFdlqdQ.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFs-Baxglj2V.js → useFs-BidCpfLX.js} +1 -1
  148. package/src/assets/web-panel/assets/usePersonalDataHub-C5mHttA9.js +1 -0
  149. package/src/assets/web-panel/assets/{vnode-mIRkdT7o.js → vnode-BrbcRiHZ.js} +1 -1
  150. package/src/assets/web-panel/assets/{zoom-HzI5DlH_.js → zoom-PISX7AkR.js} +1 -1
  151. package/src/assets/web-panel/index.html +1 -1
  152. package/src/commands/__tests__/hub-wechat.test.js +45 -0
  153. package/src/commands/agenda.js +22 -6
  154. package/src/commands/agent.js +3 -3
  155. package/src/commands/background-session.js +16 -6
  156. package/src/commands/batch.js +79 -27
  157. package/src/commands/changelog.js +15 -4
  158. package/src/commands/context.js +33 -1
  159. package/src/commands/eval.js +21 -6
  160. package/src/commands/hook.js +2 -2
  161. package/src/commands/hub.js +473 -39
  162. package/src/commands/init.js +212 -110
  163. package/src/commands/llm.js +22 -6
  164. package/src/commands/loop.js +9 -2
  165. package/src/commands/skill.js +13 -1
  166. package/src/commands/statusline.js +3 -3
  167. package/src/data/changelog.json +53 -5
  168. package/src/gateways/ws/personal-data-hub-protocol.js +22 -2
  169. package/src/harness/background-task-manager.js +18 -6
  170. package/src/harness/background-task-worker.js +11 -18
  171. package/src/harness/golden-transcript.js +3 -0
  172. package/src/harness/mcp-client.js +9 -15
  173. package/src/harness/worktree-isolator.js +18 -21
  174. package/src/index.js +18 -7
  175. package/src/lib/agent-core.js +5 -0
  176. package/src/lib/agent-ipc-bus.js +12 -3
  177. package/src/lib/agent-team/team-worktree.js +28 -6
  178. package/src/lib/agent-worktree.js +20 -19
  179. package/src/lib/approval-authority-store.js +891 -0
  180. package/src/lib/async-hook-supervisor.cjs +134 -24
  181. package/src/lib/async-hook-supervisor.js +47 -0
  182. package/src/lib/background-agent-supervisor.js +35 -12
  183. package/src/lib/background-interaction-resolver.js +399 -54
  184. package/src/lib/background-session-transport.js +3 -1
  185. package/src/lib/background-task-manager.js +5 -1
  186. package/src/lib/changelog.js +57 -0
  187. package/src/lib/chrome-connector.js +6 -2
  188. package/src/lib/claude-code-bridge.js +24 -8
  189. package/src/lib/cli-anything-bridge.js +82 -25
  190. package/src/lib/context-breakdown.js +82 -3
  191. package/src/lib/doctor-checkup.js +18 -6
  192. package/src/lib/eval/tasks.js +25 -31
  193. package/src/lib/event-runtime-host.js +225 -0
  194. package/src/lib/event-runtime-store.js +102 -21
  195. package/src/lib/event-runtime-worker.js +70 -2
  196. package/src/lib/hook-runner.cjs +71 -36
  197. package/src/lib/hook-runner.js +55 -0
  198. package/src/lib/hooks-v2-producers.js +33 -8
  199. package/src/lib/hooks-v2-runtime.js +360 -40
  200. package/src/lib/host-adb-bridge.js +18 -3
  201. package/src/lib/interaction-adapter.js +66 -0
  202. package/src/lib/lsp/__tests__/benchmark.test.js +61 -0
  203. package/src/lib/lsp/__tests__/lsp-client.test.js +6 -1
  204. package/src/lib/lsp/benchmark.js +20 -4
  205. package/src/lib/lsp/lsp-client.js +6 -4
  206. package/src/lib/lsp/lsp-server-registry.js +0 -2
  207. package/src/lib/operation-fingerprint.js +107 -2
  208. package/src/lib/orchestrator.js +8 -2
  209. package/src/lib/packer/pack-update-applier.js +14 -2
  210. package/src/lib/packer/smoke-runner.js +18 -5
  211. package/src/lib/paths.js +1 -1
  212. package/src/lib/pdh-dedicated-batch-collectors.js +124 -0
  213. package/src/lib/personal-data-hub-wiring.js +327 -52
  214. package/src/lib/plugin-monitor-supervisor.js +20 -13
  215. package/src/lib/plugin-runtime/install.js +10 -3
  216. package/src/lib/process-execution-broker/credential-agent.js +954 -111
  217. package/src/lib/process-execution-broker/index.js +369 -85
  218. package/src/lib/process-execution-broker/platform-sandbox.js +320 -140
  219. package/src/lib/provider-http-error.js +94 -0
  220. package/src/lib/remote-approval-bridge.js +222 -26
  221. package/src/lib/repl-bang-memorize.js +10 -2
  222. package/src/lib/repl-goal.js +19 -2
  223. package/src/lib/settings-hook-events.cjs +13 -8
  224. package/src/lib/settings-hook-events.js +20 -0
  225. package/src/lib/side-effect-ledger-store.js +65 -14
  226. package/src/lib/skill-loader.js +215 -12
  227. package/src/lib/skill-packs/generator.js +18 -9
  228. package/src/lib/skill-process-broker.js +85 -0
  229. package/src/lib/slash-commands.js +10 -2
  230. package/src/lib/status-line.cjs +28 -7
  231. package/src/lib/status-line.js +33 -0
  232. package/src/lib/sub-agent-context.js +42 -0
  233. package/src/lib/turn-binding-store.js +64 -15
  234. package/src/lib/turn-binding.js +85 -16
  235. package/src/repl/agent-repl.js +88 -49
  236. package/src/repl/remote-approval.js +13 -13
  237. package/src/repl/repl-turn-binding.js +46 -16
  238. package/src/runtime/agent-core.js +419 -84
  239. package/src/runtime/coding-agent-contract-shared.cjs +16 -0
  240. package/src/runtime/headless-runner.js +172 -44
  241. package/src/runtime/headless-stream.js +221 -11
  242. package/src/runtime/session-slash-commands.js +506 -0
  243. package/src/skills/video-editing/extractors/audio-extractor.js +13 -5
  244. package/src/skills/video-editing/extractors/video-extractor.js +13 -3
  245. package/src/skills/video-editing/media-process.js +20 -0
  246. package/src/skills/video-editing/render/audio-mix.js +13 -3
  247. package/src/skills/video-editing/render/ffmpeg-concat.js +7 -2
  248. package/src/skills/video-editing/render/ffmpeg-extract.js +7 -2
  249. package/src/workers/background-agent-worker.js +76 -40
  250. package/src/assets/web-panel/assets/AppLayout-Duu8xR14.js +0 -9
  251. package/src/assets/web-panel/assets/Dashboard-CXrd5gAw.js +0 -3
  252. package/src/assets/web-panel/assets/MobileProjects-NZvvfDME.js +0 -1
  253. package/src/assets/web-panel/assets/OrderTableRenderer-C48mu09U.js +0 -1
  254. package/src/assets/web-panel/assets/PersonalDataHub-AX3ypUDV.js +0 -9
  255. package/src/assets/web-panel/assets/Projects-Cc7FC9-e.js +0 -1
  256. package/src/assets/web-panel/assets/Terminal-CjTZPa37.js +0 -3
  257. package/src/assets/web-panel/assets/devWarning-BT46Y_QI.js +0 -1
  258. package/src/assets/web-panel/assets/index-B7nuIywP.js +0 -1
  259. package/src/assets/web-panel/assets/index-ycwAfC-i.js +0 -1
  260. package/src/assets/web-panel/assets/usePersonalDataHub-B4NkcLaP.js +0 -1
@@ -1,30 +1,109 @@
1
1
  /**
2
2
  * Platform-specific sandbox enforcement for ProcessExecutionBroker (P0-1)
3
3
  *
4
- * Implements OS-level sandboxing primitives:
5
- * - Windows: Job Object + restricted token + basic mitigations
6
- * - macOS: Seatbelt sandbox profiles
7
- * - Linux: seccomp-bpf (when available) + NO_NEW_PRIVS + resource limits
4
+ * Platform enforcement currently available:
5
+ * - macOS: Seatbelt sandbox-exec profiles
6
+ * - Linux: prlimit resource-limit wrapper
7
+ * - Windows: explicitly unavailable until a native Job Object + restricted
8
+ * token adapter is installed
8
9
  *
9
10
  * Security model:
10
- * 1. All child processes are placed into an isolated sandbox before exec
11
- * 2. Filesystem access is restricted by default (explicit allowlist only)
12
- * 3. Network access is blocked by default (explicit opt-in)
13
- * 4. Privilege escalation is prevented (NO_NEW_PRIVS, restricted tokens)
14
- * 5. Resource limits prevent DoS (CPU, memory, process count)
11
+ * Adapters return a truthful spawn plan. An unavailable primitive is never
12
+ * represented as applied; ProcessExecutionBroker decides whether to fail
13
+ * closed (strict mode) or record the unavailable boundary.
15
14
  *
16
15
  * Part of Phase 1 Implementation - 2026-07-22
17
16
  */
18
17
 
19
18
  import os from "node:os";
20
19
  import path from "node:path";
21
- import fs from "node:fs";
20
+ import * as fs from "node:fs";
22
21
  import crypto from "node:crypto";
23
- import { createRequire } from "node:module";
22
+ const DEFAULT_RUNTIME = Object.freeze({
23
+ platform: os.platform(),
24
+ fs,
25
+ tmpdir: () => os.tmpdir(),
26
+ homedir: () => os.homedir(),
27
+ randomBytes: (size) => crypto.randomBytes(size),
28
+ resolvePath: (value) => path.resolve(value),
29
+ joinPath: (...parts) => path.join(...parts),
30
+ });
31
+
32
+ function resolveRuntime(overrides = {}) {
33
+ return { ...DEFAULT_RUNTIME, ...overrides };
34
+ }
24
35
 
25
- const require = createRequire(import.meta.url);
36
+ /**
37
+ * A native `spawn(..., { shell: true })` asks Node to execute one command
38
+ * string through the platform shell. Once a sandbox wrapper becomes the
39
+ * executable, leaving `shell: true` makes the host shell parse the wrapper
40
+ * argv instead, and the original command is no longer one atomic `-c`
41
+ * payload. Linux `prlimit` then tries to exec a file literally named
42
+ * "node script.js"; macOS Seatbelt has the same ambiguity.
43
+ *
44
+ * Materialize the requested POSIX shell before adding either wrapper. The
45
+ * sandbox executable itself is always spawned directly.
46
+ */
47
+ function normalizeWrappedInvocation(command, args, spawnOpts, platform) {
48
+ if (!spawnOpts?.shell || platform === "win32") {
49
+ return {
50
+ command,
51
+ args: [...(args || [])],
52
+ options: { ...(spawnOpts || {}) },
53
+ };
54
+ }
26
55
 
27
- const platform = os.platform();
56
+ const shell =
57
+ typeof spawnOpts.shell === "string" ? spawnOpts.shell : "/bin/sh";
58
+ const shellCommand = [command, ...(args || [])].map(String).join(" ");
59
+ return {
60
+ command: shell,
61
+ args: ["-c", shellCommand],
62
+ options: { ...spawnOpts, shell: false },
63
+ };
64
+ }
65
+
66
+ /**
67
+ * Every platform adapter returns the same immutable spawn-plan shape. The
68
+ * broker must consume `command`, `args`, and `options` from this object rather
69
+ * than relying on adapters to mutate caller-owned values.
70
+ *
71
+ * A required post-spawn enforcement step must declare whether it is
72
+ * synchronous. ProcessExecutionBroker.spawn() is synchronous, so strict mode
73
+ * rejects an asynchronous required step before starting the child.
74
+ *
75
+ * @param {Object} input
76
+ * @returns {{
77
+ * contractVersion: 1,
78
+ * applied: boolean,
79
+ * platform: string,
80
+ * profile: string,
81
+ * command: string,
82
+ * args: string[],
83
+ * options: Object,
84
+ * enforcement: string|null,
85
+ * reason: string|null,
86
+ * cleanup?: Function,
87
+ * postSpawn: {required: boolean, mode: "none"|"sync"|"async"}
88
+ * }}
89
+ */
90
+ function createSandboxPlan(input) {
91
+ const postSpawn = Object.freeze({
92
+ required: false,
93
+ mode: "none",
94
+ ...(input.postSpawn || {}),
95
+ });
96
+ return Object.freeze({
97
+ contractVersion: 1,
98
+ applied: false,
99
+ enforcement: null,
100
+ reason: null,
101
+ ...input,
102
+ args: Object.freeze([...(input.args || [])]),
103
+ options: Object.freeze({ ...(input.options || {}) }),
104
+ postSpawn,
105
+ });
106
+ }
28
107
 
29
108
  // ---------------------------------------------------------------------------
30
109
  // macOS Seatbelt Sandbox
@@ -41,7 +120,8 @@ const platform = os.platform();
41
120
  * @param {boolean} [opts.allowExec=true] - Allow process exec (subprocess spawning)
42
121
  * @returns {string} sandbox profile content
43
122
  */
44
- export function generateMacSeatbeltProfile(opts = {}) {
123
+ export function generateMacSeatbeltProfile(opts = {}, runtimeOverrides = {}) {
124
+ const runtime = resolveRuntime(runtimeOverrides);
45
125
  const {
46
126
  allowRead = [],
47
127
  allowWrite = [],
@@ -54,9 +134,9 @@ export function generateMacSeatbeltProfile(opts = {}) {
54
134
  "(deny default)",
55
135
  // Basic system operations always allowed
56
136
  "(allow signal (target self))",
57
- "(allow process-exec (literal \"/usr/bin/env\"))",
58
- "(allow process-exec (literal \"/bin/sh\"))",
59
- "(allow process-exec (literal \"/bin/bash\"))",
137
+ '(allow process-exec (literal "/usr/bin/env"))',
138
+ '(allow process-exec (literal "/bin/sh"))',
139
+ '(allow process-exec (literal "/bin/bash"))',
60
140
  "(allow sysctl-read)",
61
141
  "(allow mach-lookup)",
62
142
  ];
@@ -72,12 +152,12 @@ export function generateMacSeatbeltProfile(opts = {}) {
72
152
 
73
153
  // Allow read/write to specific paths
74
154
  for (const p of allowRead) {
75
- const abs = path.resolve(p);
155
+ const abs = runtime.resolvePath(p);
76
156
  lines.push(`(allow file-read* (subpath "${abs}"))`);
77
157
  }
78
158
 
79
159
  for (const p of allowWrite) {
80
- const abs = path.resolve(p);
160
+ const abs = runtime.resolvePath(p);
81
161
  lines.push(`(allow file-read* file-write* (subpath "${abs}"))`);
82
162
  }
83
163
 
@@ -99,165 +179,235 @@ export function generateMacSeatbeltProfile(opts = {}) {
99
179
  *
100
180
  * @param {string} command - Original command
101
181
  * @param {string[]} args - Original args
102
- * @param {Object} spawnOpts - Spawn options to mutate (adds sandbox-exec wrapper)
182
+ * @param {Object} spawnOpts - Original spawn options
103
183
  * @param {Object} sandboxOpts - Sandbox options
104
184
  */
105
- export function applyMacSandbox(command, args, spawnOpts, sandboxOpts = {}) {
106
- if (platform !== "darwin") return { applied: false };
185
+ export function applyMacSandbox(
186
+ command,
187
+ args,
188
+ spawnOpts,
189
+ sandboxOpts = {},
190
+ runtimeOverrides = {},
191
+ ) {
192
+ const runtime = resolveRuntime(runtimeOverrides);
193
+ const invocation = normalizeWrappedInvocation(
194
+ command,
195
+ args,
196
+ spawnOpts,
197
+ runtime.platform,
198
+ );
199
+ const base = {
200
+ platform: runtime.platform,
201
+ profile: sandboxOpts.profileName || "default",
202
+ command,
203
+ args,
204
+ options: { ...(spawnOpts || {}) },
205
+ };
206
+ if (runtime.platform !== "darwin") {
207
+ return createSandboxPlan({
208
+ ...base,
209
+ reason: "platform_mismatch",
210
+ });
211
+ }
212
+
213
+ // A deny-by-default Seatbelt profile cannot safely infer the filesystem,
214
+ // IPC, and inherited-descriptor access required by an arbitrary command.
215
+ // Keep the boundary truthful for the broker's implicit default profile:
216
+ // non-strict mode records the unavailable primitive and executes the
217
+ // original invocation, while strict mode fails closed. Explicit strict or
218
+ // network-only profiles still opt in to the sandbox-exec wrapper below.
219
+ if ((sandboxOpts.profileName || "default") === "default") {
220
+ return createSandboxPlan({
221
+ ...base,
222
+ reason: "macos_default_profile_requires_explicit_policy",
223
+ });
224
+ }
225
+
226
+ const sandboxExecutable = "/usr/bin/sandbox-exec";
227
+ if (!runtime.fs.existsSync(sandboxExecutable)) {
228
+ return createSandboxPlan({
229
+ ...base,
230
+ reason: "macos_sandbox_exec_unavailable",
231
+ });
232
+ }
107
233
 
108
234
  // Generate temporary profile file
109
- const profileContent = generateMacSeatbeltProfile(sandboxOpts);
110
- const profilePath = path.join(
111
- os.tmpdir(),
112
- `chainless-sb-${crypto.randomBytes(8).toString("hex")}.sb`,
235
+ const profileContent = generateMacSeatbeltProfile(
236
+ sandboxOpts,
237
+ runtimeOverrides,
238
+ );
239
+ const profilePath = runtime.joinPath(
240
+ runtime.tmpdir(),
241
+ `chainless-sb-${runtime.randomBytes(8).toString("hex")}.sb`,
113
242
  );
114
243
 
115
- fs.writeFileSync(profilePath, profileContent, { mode: 0o600 });
244
+ runtime.fs.writeFileSync(profilePath, profileContent, { mode: 0o600 });
116
245
 
117
246
  // Wrap command with sandbox-exec
118
- const newArgs = ["-f", profilePath, command, ...args];
247
+ const newArgs = ["-f", profilePath, invocation.command, ...invocation.args];
119
248
 
120
- return {
249
+ return createSandboxPlan({
250
+ ...base,
121
251
  applied: true,
122
- wrapper: "sandbox-exec",
123
- profilePath,
124
- newCommand: "sandbox-exec",
125
- newArgs,
252
+ enforcement: "macos-seatbelt",
253
+ command: sandboxExecutable,
254
+ args: newArgs,
255
+ options: invocation.options,
126
256
  cleanup: () => {
127
257
  try {
128
- fs.unlinkSync(profilePath);
258
+ runtime.fs.unlinkSync(profilePath);
129
259
  } catch {
130
260
  // ignore cleanup errors
131
261
  }
132
262
  },
133
- };
263
+ });
134
264
  }
135
265
 
136
266
  // ---------------------------------------------------------------------------
137
- // Windows Job Object Sandbox
267
+ // Windows Job Object availability
138
268
  // ---------------------------------------------------------------------------
139
269
 
140
270
  /**
141
- * Apply Windows Job Object limits + basic mitigations.
142
- *
143
- * On Windows we:
144
- * 1. Set CREATE_BREAKAWAY_FROM_JOB to ensure child can be placed into our own job
145
- * 2. Add JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE so children die when parent exits
146
- * 3. Set basic process memory/CPU limits if specified
147
- * 4. Set creation flags for restricted token (best-effort)
148
- *
149
- * Note: Full Win32 Job Object API requires ffi/n-rap invocation.
150
- * This function sets the spawn flags and returns metadata for post-spawn association.
271
+ * Report Windows sandbox availability. Node's child_process API cannot create
272
+ * and synchronously assign a Job Object or restricted token by itself.
151
273
  *
152
274
  * @param {string} command
153
275
  * @param {string[]} args
154
276
  * @param {Object} spawnOpts
155
277
  * @param {Object} sandboxOpts
156
278
  */
157
- export function applyWindowsSandbox(command, args, spawnOpts, sandboxOpts = {}) {
158
- if (platform !== "win32") return { applied: false };
159
-
160
- // Set creation flags for Job Object support
161
- // CREATE_BREAKAWAY_FROM_JOB = 0x01000000
162
- // CREATE_NO_WINDOW = 0x08000000
163
- const CREATE_BREAKAWAY_FROM_JOB = 0x01000000;
164
- const CREATE_NO_WINDOW = 0x08000000;
165
-
166
- const existingFlags = spawnOpts.windowsHide
167
- ? CREATE_NO_WINDOW
168
- : 0;
169
- spawnOpts.windowsVerbatimArguments = false;
170
-
171
- // Set environment variable to signal sandboxed mode to any child-aware tools
172
- const env = { ...(spawnOpts.env || process.env) };
173
- env.CHAINLESS_SANDBOXED = "1";
174
- spawnOpts.env = env;
175
-
176
- return {
177
- applied: true,
178
- needsPostSpawn: true,
179
- jobFlags: CREATE_BREAKAWAY_FROM_JOB | existingFlags,
180
- limits: sandboxOpts.limits || null,
279
+ export function applyWindowsSandbox(
280
+ command,
281
+ args,
282
+ spawnOpts,
283
+ sandboxOpts = {},
284
+ runtimeOverrides = {},
285
+ ) {
286
+ const runtime = resolveRuntime(runtimeOverrides);
287
+ const base = {
288
+ platform: runtime.platform,
289
+ profile: sandboxOpts.profileName || "default",
290
+ command,
291
+ args,
292
+ options: spawnOpts,
181
293
  };
294
+ if (runtime.platform !== "win32") {
295
+ return createSandboxPlan({
296
+ ...base,
297
+ reason: "platform_mismatch",
298
+ });
299
+ }
300
+
301
+ // Node does not expose Job Object or restricted-token primitives. Mark the
302
+ // platform unavailable instead of treating CREATE_NO_WINDOW or an
303
+ // environment marker as a security boundary. A future native adapter may
304
+ // return an applied plan with a synchronous postSpawn step.
305
+ return createSandboxPlan({
306
+ ...base,
307
+ reason: "windows_native_job_object_unavailable",
308
+ });
182
309
  }
183
310
 
184
311
  /**
185
- * Post-spawn: associate a Windows process with a Job Object.
186
- * Uses PowerShell for lightweight isolation (best-effort; full ffi approach
187
- * requires koffi/n-rap).
312
+ * Reject an attempted Windows post-spawn association until a native adapter is
313
+ * available.
188
314
  *
189
315
  * @param {ChildProcess} proc - The spawned child process
190
316
  * @param {Object} sandboxResult - Result from applyWindowsSandbox
191
317
  */
192
- export async function postSpawnWindowsSandbox(proc, sandboxResult) {
193
- if (platform !== "win32" || !proc.pid) return;
194
-
195
- // Best-effort: set CPU affinity and priority via Node's built-in methods
196
- try {
197
- proc.renice && proc.renice(10); // Lower priority
198
- } catch {
199
- // ignore
318
+ export function postSpawnWindowsSandbox(
319
+ proc,
320
+ sandboxResult,
321
+ runtimeOverrides = {},
322
+ ) {
323
+ const runtime = resolveRuntime(runtimeOverrides);
324
+ if (runtime.platform !== "win32" || !sandboxResult?.postSpawn?.required) {
325
+ return;
200
326
  }
201
-
202
- // Full Job Object association via ffi would go here when koffi is available.
203
- // For now, we rely on:
204
- // 1. Parent process explicitly killing children on exit (broker handles this)
205
- // 2. CREATE_NO_WINDOW for UI isolation
206
- // 3. Environment variable signaling sandbox mode
327
+ const error = new Error(
328
+ "Windows native Job Object enforcement is unavailable",
329
+ );
330
+ error.code = "ERR_WINDOWS_SANDBOX_UNAVAILABLE";
331
+ throw error;
207
332
  }
208
333
 
209
334
  // ---------------------------------------------------------------------------
210
- // Linux seccomp/resource-limit Sandbox
335
+ // Linux resource-limit enforcement
211
336
  // ---------------------------------------------------------------------------
212
337
 
213
338
  /**
214
- * Apply Linux sandbox: NO_NEW_PRIVS + rlimits + (optionally) seccomp.
215
- *
216
- * For Node.js spawned children, the most portable approach without native deps
217
- * is to use `prlimit` (util-linux) wrapper and set `child_process` uid/gid/groups.
339
+ * Apply Linux resource limits through the util-linux `prlimit` wrapper.
218
340
  *
219
341
  * @param {string} command
220
342
  * @param {string[]} args
221
343
  * @param {Object} spawnOpts
222
344
  * @param {Object} sandboxOpts
223
345
  */
224
- export function applyLinuxSandbox(command, args, spawnOpts, sandboxOpts = {}) {
225
- if (platform !== "linux") return { applied: false };
346
+ export function applyLinuxSandbox(
347
+ command,
348
+ args,
349
+ spawnOpts,
350
+ sandboxOpts = {},
351
+ runtimeOverrides = {},
352
+ ) {
353
+ const runtime = resolveRuntime(runtimeOverrides);
354
+ const invocation = normalizeWrappedInvocation(
355
+ command,
356
+ args,
357
+ spawnOpts,
358
+ runtime.platform,
359
+ );
360
+ const base = {
361
+ platform: runtime.platform,
362
+ profile: sandboxOpts.profileName || "default",
363
+ command,
364
+ args,
365
+ options: { ...(spawnOpts || {}) },
366
+ };
367
+ if (runtime.platform !== "linux") {
368
+ return createSandboxPlan({
369
+ ...base,
370
+ reason: "platform_mismatch",
371
+ });
372
+ }
226
373
 
227
374
  const { limits = {} } = sandboxOpts;
228
375
 
229
- // Apply resource limits via spawn options (if supported by Node version)
230
- // Node 19+ supports `gid`, `uid` in spawn options for privilege dropping
231
- spawnOpts.gid = spawnOpts.gid || undefined;
232
- spawnOpts.uid = spawnOpts.uid || undefined;
233
-
234
- // Mark environment
235
- const env = { ...(spawnOpts.env || process.env) };
236
- env.CHAINLESS_SANDBOXED = "1";
237
- spawnOpts.env = env;
238
-
239
- // If we want hard limits and prlimit is available, wrap the command.
240
- // Prlimit path: /usr/bin/prlimit
241
- let newCommand = command;
242
- let newArgs = [...args];
243
-
244
376
  const prlimitParts = [];
245
377
  if (limits.cpu) prlimitParts.push(`--cpu=${limits.cpu}`);
246
378
  if (limits.as) prlimitParts.push(`--as=${limits.as}`);
247
379
  if (limits.nofile) prlimitParts.push(`--nofile=${limits.nofile}`);
248
380
  if (limits.nproc) prlimitParts.push(`--nproc=${limits.nproc}`);
249
381
 
250
- if (prlimitParts.length > 0 && fs.existsSync("/usr/bin/prlimit")) {
251
- newCommand = "/usr/bin/prlimit";
252
- newArgs = [...prlimitParts, command, ...args];
382
+ if (prlimitParts.length === 0) {
383
+ return createSandboxPlan({
384
+ ...base,
385
+ reason: "linux_resource_limits_not_configured",
386
+ });
387
+ }
388
+ if (!runtime.fs.existsSync("/usr/bin/prlimit")) {
389
+ return createSandboxPlan({
390
+ ...base,
391
+ reason: "linux_prlimit_unavailable",
392
+ });
253
393
  }
254
394
 
255
- return {
256
- applied: true,
257
- newCommand,
258
- newArgs,
259
- needsSetSid: true, // Use setsid to create new process group for clean killing
395
+ const options = {
396
+ ...invocation.options,
397
+ env: {
398
+ ...(invocation.options.env || process.env),
399
+ CHAINLESS_SANDBOXED: "1",
400
+ },
260
401
  };
402
+
403
+ return createSandboxPlan({
404
+ ...base,
405
+ applied: true,
406
+ enforcement: "linux-prlimit",
407
+ command: "/usr/bin/prlimit",
408
+ args: [...prlimitParts, "--", invocation.command, ...invocation.args],
409
+ options,
410
+ });
261
411
  }
262
412
 
263
413
  // ---------------------------------------------------------------------------
@@ -269,75 +419,105 @@ export function applyLinuxSandbox(command, args, spawnOpts, sandboxOpts = {}) {
269
419
  *
270
420
  * @param {string} command
271
421
  * @param {string[]} args
272
- * @param {Object} spawnOpts - Will be MUTATED with sandbox flags/env
422
+ * @param {Object} spawnOpts - Original spawn options
273
423
  * @param {"default"|"strict"|"network-only"} profileName
274
- * @returns {{ applied: boolean, wrapper?: string, newCommand?: string, newArgs?: string[], cleanup?: Function, needsPostSpawn?: boolean }}
424
+ * @returns {ReturnType<typeof createSandboxPlan>}
275
425
  */
276
- export function applySandbox(command, args, spawnOpts, profileName = "default") {
426
+ export function applySandbox(
427
+ command,
428
+ args,
429
+ spawnOpts,
430
+ profileName = "default",
431
+ runtimeOverrides = {},
432
+ ) {
433
+ const runtime = resolveRuntime(runtimeOverrides);
277
434
  const profiles = {
278
435
  default: {
279
436
  allowNetwork: false,
280
437
  allowExec: true,
281
- allowRead: [os.homedir(), "/tmp"],
282
- allowWrite: [os.tmpdir()],
438
+ allowRead: [runtime.homedir(), "/tmp"],
439
+ allowWrite: [runtime.tmpdir()],
283
440
  limits: {
441
+ // RLIMIT_NPROC is intentionally omitted. Linux applies it per real
442
+ // user ID rather than to this child tree, so it can starve unrelated
443
+ // CI workers and prevent Node from creating its own helper threads.
284
444
  cpu: 30, // seconds
285
445
  nofile: 256,
286
- nproc: 64,
287
446
  },
288
447
  },
289
448
  strict: {
290
449
  allowNetwork: false,
291
450
  allowExec: false,
292
451
  allowRead: [],
293
- allowWrite: [os.tmpdir()],
452
+ allowWrite: [runtime.tmpdir()],
294
453
  limits: {
295
454
  cpu: 10,
296
455
  as: 256 * 1024 * 1024, // 256MB address space
297
456
  nofile: 64,
298
- nproc: 8,
299
457
  },
300
458
  },
301
459
  "network-only": {
302
460
  allowNetwork: true,
303
461
  allowExec: true,
304
- allowRead: [os.homedir()],
305
- allowWrite: [os.tmpdir()],
462
+ allowRead: [runtime.homedir()],
463
+ allowWrite: [runtime.tmpdir()],
306
464
  limits: {
307
465
  cpu: 60,
308
466
  nofile: 512,
309
- nproc: 128,
310
467
  },
311
468
  },
312
469
  };
313
470
 
314
- const profile = profiles[profileName] || profiles.default;
471
+ const profile = {
472
+ ...(profiles[profileName] || profiles.default),
473
+ profileName: profiles[profileName] ? profileName : "default",
474
+ };
315
475
 
316
476
  // Dispatch to platform handler
317
- if (platform === "darwin") {
318
- return applyMacSandbox(command, args, spawnOpts, profile);
477
+ if (runtime.platform === "darwin") {
478
+ return applyMacSandbox(command, args, spawnOpts, profile, runtimeOverrides);
319
479
  }
320
- if (platform === "win32") {
321
- return applyWindowsSandbox(command, args, spawnOpts, profile);
480
+ if (runtime.platform === "win32") {
481
+ return applyWindowsSandbox(
482
+ command,
483
+ args,
484
+ spawnOpts,
485
+ profile,
486
+ runtimeOverrides,
487
+ );
322
488
  }
323
- if (platform === "linux") {
324
- return applyLinuxSandbox(command, args, spawnOpts, profile);
489
+ if (runtime.platform === "linux") {
490
+ return applyLinuxSandbox(
491
+ command,
492
+ args,
493
+ spawnOpts,
494
+ profile,
495
+ runtimeOverrides,
496
+ );
325
497
  }
326
498
 
327
499
  // Unknown platform - no sandbox applied
328
- return { applied: false };
500
+ return createSandboxPlan({
501
+ platform: runtime.platform,
502
+ profile: profile.profileName,
503
+ command,
504
+ args,
505
+ options: spawnOpts,
506
+ reason: "unsupported_platform",
507
+ });
329
508
  }
330
509
 
331
510
  /**
332
511
  * Post-spawn sandbox setup (called after child process starts).
333
- * Currently only needed on Windows for Job Object association.
512
+ * Reserved for adapters that require a synchronous native association step.
334
513
  *
335
514
  * @param {ChildProcess} proc
336
515
  * @param {Object} sandboxResult
337
516
  */
338
- export async function postSpawnSandbox(proc, sandboxResult) {
339
- if (platform === "win32" && sandboxResult?.needsPostSpawn) {
340
- await postSpawnWindowsSandbox(proc, sandboxResult);
517
+ export function postSpawnSandbox(proc, sandboxResult, runtimeOverrides = {}) {
518
+ const runtime = resolveRuntime(runtimeOverrides);
519
+ if (runtime.platform === "win32" && sandboxResult?.postSpawn?.required) {
520
+ return postSpawnWindowsSandbox(proc, sandboxResult, runtimeOverrides);
341
521
  }
342
522
  }
343
523