chainlesschain 0.162.170 → 0.162.172

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 (186) hide show
  1. package/bin/chainlesschain.js +8 -0
  2. package/package.json +6 -1
  3. package/src/assets/web-panel/assets/{AIOps-BTXN24I3.js → AIOps-oKCWU-LK.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-BBB1VF4j.js → ActionButton-4CBfc5E4.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-BVCXq0k6.js → Analytics-BEmR-k_b.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-C3EOo2s5.js → AppLayout-D6a4ZnrC.js} +5 -5
  7. package/src/assets/web-panel/assets/{Artifacts-CsJTZSMv.js → Artifacts-BRWIHCPl.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-CP0AllJ_.js → Audit-CzGKlkTc.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-BCAjs08m.js → BackgroundAgents-CmMYN10o.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-BxQI5XH4.js → Backup-CJ6e0ukD.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-Bu-PNzC5.js → BaseInput-BpEvDrNt.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-DjPQynup.js → Chat-wWuwwjKu.js} +4 -4
  13. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CygkRopu.js → ChatBubbleRenderer-CJLyGo_u.js} +1 -1
  14. package/src/assets/web-panel/assets/{Checkbox-BxL6xm7Z.js → Checkbox-C6pW60Br.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-CcyB7h_6.js → Codegen-DF-nP22Y.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-8NQiKJJx.js → Col-BuueEwZW.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-B31qy5OS.js → Community-DuE0Yzwr.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-C-5fAsZ4.js → Compact-BrHim8EB.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-BTSccvF0.js → Compliance-DgAet8f_.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-BXctU9IK.js → Cowork-B9wY05lx.js} +3 -3
  21. package/src/assets/web-panel/assets/{Cron-CxVFX9NG.js → Cron-CvNBxfJX.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-DEF3dq8M.js → Crosschain-BnZRENa0.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-BmKcE9he.js → DID-DiqYLHTI.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-CECBq_wG.js → Dashboard-t3SsRzZL.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-U-iuPB0n.js → Dropdown-BCjMLam9.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-D8BIlSPL.js → EmailListRenderer-D2v9-IHJ.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-BzQGfUH-.js → FamilyGuardDashboard-_iQu35qa.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-4_WlOqLZ.js → Federation-Bkty8VqB.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-gtrW-DdF.js → FormItemContext-DdPW81BY.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-BLcvJJB6.js → GenericCardRenderer-DrNYM4Zj.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-Bk0janGD.js → Git-BjF-B2h0.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-CcfyMlV8.js → Governance-DPhGdJ1v.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-CBLrAf4M.js → Inference--PPksOVj.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-ClguhteZ.js → KnowledgeGraph-y5WdV_JV.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-Dp_oeKfJ.js → Logs-B6_x7zba.js} +2 -2
  36. package/src/assets/web-panel/assets/MarkdownRenderer-Bg8zSyF8.js +1 -0
  37. package/src/assets/web-panel/assets/{Marketplace-BHk50smM.js → Marketplace-CHpfMu1A.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-BAY3CV6J.js → McpTools-qqjtX3Cf.js} +5 -5
  39. package/src/assets/web-panel/assets/{Memory-w0pG2AKx.js → Memory-hASSgxbw.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge-C0VkDUE3.js → MobileBridge-Dwh7Bhcf.js} +1 -1
  41. package/src/assets/web-panel/assets/{MobileProjects-BCvQ80I9.js → MobileProjects-D09voh7W.js} +1 -1
  42. package/src/assets/web-panel/assets/{Mtc-DSIl41Tt.js → Mtc-9G1dXeId.js} +5 -5
  43. package/src/assets/web-panel/assets/{MtcAudit-D1mzUlIr.js → MtcAudit-CWtYXj6f.js} +2 -2
  44. package/src/assets/web-panel/assets/{Multisig-CeJz4VSS.js → Multisig-bDI0EnDk.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-_O3aweu8.js → NLProgramming-CTanRaBP.js} +1 -1
  46. package/src/assets/web-panel/assets/{Notes-Dt7_pO86.js → Notes-BdQENJFv.js} +3 -3
  47. package/src/assets/web-panel/assets/{NotificationSettings-Dhg3Nktv.js → NotificationSettings-JvnQdStO.js} +1 -1
  48. package/src/assets/web-panel/assets/{OrderTableRenderer-QsAPcTb2.js → OrderTableRenderer-BMGL9RPJ.js} +1 -1
  49. package/src/assets/web-panel/assets/{Organization-BuiaUPkv.js → Organization-sBZnIb2D.js} +4 -4
  50. package/src/assets/web-panel/assets/{Overflow-C3jb6knl.js → Overflow-CzOhNGE6.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-BOMyrLkb.js → P2P-D_D2yqda.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser-UvLStCgS.js → PdhVaultBrowser-D5lKd_Kx.js} +3 -3
  53. package/src/assets/web-panel/assets/{Permissions-B9cN0dJH.js → Permissions-L5s-wENg.js} +4 -4
  54. package/src/assets/web-panel/assets/{PersonalDataHub-DNjW5qro.js → PersonalDataHub-iI49x6cH.js} +3 -3
  55. package/src/assets/web-panel/assets/{Pipeline-CFLyZ6Sh.js → Pipeline-DPHqyk09.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-D3w6vOxf.js → Privacy-B-ZL9360.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-cwcVsn8K.js → ProjectInit-f05YzsN2.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-aUoAroc-.js → ProjectSettings-DZLKS6ex.js} +2 -2
  59. package/src/assets/web-panel/assets/{Projects-CrzQv7Zv.js → Projects-ButF3DyM.js} +1 -1
  60. package/src/assets/web-panel/assets/{Providers-jZaPizKR.js → Providers-CFDSXnkR.js} +1 -1
  61. package/src/assets/web-panel/assets/{QrScannerModal-DNzmwcfg.js → QrScannerModal-1N6Sdxdm.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-m-5Gwt70.js → QuickAsk-tEqRwRSR.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-CrrAjNxP.js → Recommend-D4ZVHIwz.js} +1 -1
  64. package/src/assets/web-panel/assets/{RemoteSession-BDCMjRFe.js → RemoteSession-Cqm32lhm.js} +2 -2
  65. package/src/assets/web-panel/assets/{Reputation-CPCt1Jc8.js → Reputation-BnjVsU_a.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-C-RorxHs.js → Row-DzpHyTuz.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-CnQs4TuY.js → RssFeed-Du5-ouwx.js} +3 -3
  68. package/src/assets/web-panel/assets/{Search-B1jkeFZY.js → Search-CYztyf2o.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-CGKI3vvd.js → Security-C1hVxy8Z.js} +3 -3
  70. package/src/assets/web-panel/assets/{Services-DQjesYF8.js → Services-BscEbAZ2.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-C9Ipj0A6.js → Skeleton-B2sMLqKQ.js} +1 -1
  72. package/src/assets/web-panel/assets/{Skills-D2j54i9O.js → Skills-CoHKax06.js} +1 -1
  73. package/src/assets/web-panel/assets/{Sla-xhrVjTeb.js → Sla-Bpie5KO6.js} +1 -1
  74. package/src/assets/web-panel/assets/{SpeechSettings-C6KMOUCa.js → SpeechSettings-BX63ijn5.js} +1 -1
  75. package/src/assets/web-panel/assets/{SyncSettings-CmIPU5wR.js → SyncSettings-Bf72so5A.js} +2 -2
  76. package/src/assets/web-panel/assets/{Tasks-B-T1J42r.js → Tasks-CVB2PZk4.js} +1 -1
  77. package/src/assets/web-panel/assets/{Templates-Aq669sjw.js → Templates-q0qyclJx.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant-BKWUWNXB.js → Tenant-CW-W-i0k.js} +1 -1
  79. package/src/assets/web-panel/assets/{Terminal-DEeAvA8L.js → Terminal-D7QoPiXQ.js} +2 -2
  80. package/src/assets/web-panel/assets/{TimelineRenderer-C465ySdn.js → TimelineRenderer-BaRDAbyA.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-BgVqF-bX.js → Tokens-D6U4PRW8.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-BMNHmxwH.js → Trigger-ClBDWdLo.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-B_adk89L.js → Trust-C_M6rWPq.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-Biw38mog.js → UkeySign-bXHx8s4C.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-AC-eaw5k.js → VideoEditing-BcIt_ieI.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-8lQ5_t0X.js → Wallet-Dd-4jcLs.js} +4 -4
  87. package/src/assets/web-panel/assets/{WebAuthn-JDmH_-DF.js → WebAuthn-B4F6yxQK.js} +5 -5
  88. package/src/assets/web-panel/assets/{WorkflowEditor-DHQAdITG.js → WorkflowEditor-BEHkpfJq.js} +1 -1
  89. package/src/assets/web-panel/assets/{chat-C3qauUVv.js → chat-D7hhRpIO.js} +1 -1
  90. package/src/assets/web-panel/assets/{colors-DLP70JGe.js → colors-AMRhrRzS.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-DjsoqA5t.js → compact-item-BYpsOET5.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-CfEdl1in.js → createContext-CoUkR4LQ.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-BRylvxzY.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-DWwHHlBG.js → hasIn-CJKJMKki.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-Dfka-vzJ.js → index-8pmZHnQU.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-DgQ92xdO.js → index-BBJFiZ9Y.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-VtCz3A64.js → index-BP69Ul3S.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-C8wrUFzY.js → index-BTFHYauX.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-D5VL0NYy.js → index-BUJt2ar4.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-B-rD2rhi.js → index-Bj30Aq6h.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-gu8zBhtp.js → index-BlpuqGt5.js} +1 -1
  102. package/src/assets/web-panel/assets/index-Bzvxvzlk.js +1 -0
  103. package/src/assets/web-panel/assets/{index-CgruUvB3.js → index-C19xZKIP.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-DTEcPJGf.js → index-C6bg22vc.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-C4k6JGm_.js → index-CH6XEWdj.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-C0xMzvk8.js → index-CK1Kknpl.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-UEbYl2pu.js → index-CNyLbBGj.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-Dmt1HDWZ.js → index-COg__P6M.js} +19 -19
  109. package/src/assets/web-panel/assets/{index-ArZCi1rK.js → index-CRlJOWsf.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BqPuyN4p.js → index-CScG8TAY.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-B4gCFHtB.js → index-CdL9cQIE.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-C47EiQ7d.js → index-Ck35u_0v.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-Dn2rNMmv.js → index-CkLZQtsh.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-T5emAyFT.js → index-DFoujkWD.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DbFnfyKh.js → index-DFwh0R9h.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CsEk9s04.js → index-DStN9E7o.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DTDpF8MS.js → index-DcozYrXV.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-_g5q2hF3.js → index-De5mYp86.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-Bp_WNm2_.js → index-DfEVOzNb.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-OfMwkFIo.js → index-Dfna8sKa.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-BcDeMCUK.js → index-DjbMaBLf.js} +1 -1
  122. package/src/assets/web-panel/assets/index-Dl6H3dxS.js +1 -0
  123. package/src/assets/web-panel/assets/{index-D-te-S9f.js → index-Dpl_SJuk.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DKsWujXP.js → index-DyF9uYzB.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BydBh7oT.js → index-HF3GvATm.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DAcBi6F-.js → index-OJmXGn8n.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CNeLedtU.js → index-ZPdNPhUq.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Ds1BfT_C.js → index-djikyGz3.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CbF27GqZ.js → index-gQWWnP3_.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CnhJbWsl.js → index-owVbLJnH.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-Lh0e2afo.js → index-tWEDZHzj.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-DbjUePgq.js → index-ttTl376q.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-nuZaMsMy.js → index-z5rYvstM.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-C_pMmi75.js → initDefaultProps-B_Uk-wzg.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-BvKgS96o.js → motion-ez7H8y8b.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-C-1U4R1I.js → move-CKWUhhhX.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-D6BC968-.js → mtc-parser-DkNl7ocj.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-DxOZvcGQ.js → omit-C0uA2ytw.js} +1 -1
  139. package/src/assets/web-panel/assets/{pickAttrs-LpzmHdkw.js → pickAttrs-CySaWMPl.js} +1 -1
  140. package/src/assets/web-panel/assets/{placementArrow-Bm--qom1.js → placementArrow-BWL3-3xo.js} +1 -1
  141. package/src/assets/web-panel/assets/{responsiveObserve-CVZZlhJf.js → responsiveObserve-BRy_wJog.js} +1 -1
  142. package/src/assets/web-panel/assets/{slide-DD1xINGx.js → slide-DmmvSaBD.js} +1 -1
  143. package/src/assets/web-panel/assets/{statusUtils-LrjHAy63.js → statusUtils-C_7SYY0K.js} +1 -1
  144. package/src/assets/web-panel/assets/{styleChecker-BqknYxTe.js → styleChecker-DYgBJGDh.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFlexGapSupport-Dljy3diT.js → useFlexGapSupport-nPkoZkT6.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFs-OedUtPLc.js → useFs-CzpsfP4_.js} +1 -1
  147. package/src/assets/web-panel/assets/{usePersonalDataHub-Cz-kxbP_.js → usePersonalDataHub-Bo2vvMWl.js} +1 -1
  148. package/src/assets/web-panel/assets/{vnode-C8ZuTk8W.js → vnode-D-hXAnHb.js} +1 -1
  149. package/src/assets/web-panel/assets/{zoom-CjbgJYXQ.js → zoom-DW7seTGG.js} +1 -1
  150. package/src/assets/web-panel/index.html +1 -1
  151. package/src/commands/agent.js +39 -14
  152. package/src/commands/background-session.js +12 -1
  153. package/src/commands/permissions.js +24 -1
  154. package/src/gateways/ws/ws-agent-handler.js +26 -1
  155. package/src/gateways/ws/ws-approval-gate.js +131 -0
  156. package/src/index.js +63 -845
  157. package/src/lib/agent-ipc-bus.js +331 -0
  158. package/src/lib/agent-worktree.js +173 -5
  159. package/src/lib/background-agent-supervisor.js +193 -4
  160. package/src/lib/context-source-ledger.js +164 -0
  161. package/src/lib/execution-trace/index.js +10 -0
  162. package/src/lib/execution-trace/metrics-collector.js +218 -0
  163. package/src/lib/execution-trace/trace-context.js +182 -0
  164. package/src/lib/hook-manager.js +17 -0
  165. package/src/lib/hooks-v2-runtime.js +278 -0
  166. package/src/lib/interaction-adapter.js +26 -5
  167. package/src/lib/metrics-collector.js +127 -0
  168. package/src/lib/observability/index.js +33 -0
  169. package/src/lib/observability/otlp-exporter.js +260 -0
  170. package/src/lib/otlp-exporter.js +45 -0
  171. package/src/lib/process-execution-broker/SPAWN_AUDIT_REPORT.md +117 -0
  172. package/src/lib/process-execution-broker/index.js +450 -0
  173. package/src/lib/process-execution-broker/patch-child-process.js +50 -0
  174. package/src/lib/process-execution-broker/spawn-audit.json +3814 -0
  175. package/src/lib/repl-rewind.js +62 -14
  176. package/src/lib/runtime-provenance-ledger.js +190 -0
  177. package/src/lib/session-hooks.js +41 -0
  178. package/src/lib/turn-binding.js +134 -0
  179. package/src/program-base.js +4 -1
  180. package/src/repl/agent-repl.js +77 -3
  181. package/src/repl/repl-turn-binding.js +91 -0
  182. package/src/runtime/headless-runner.js +59 -0
  183. package/src/assets/web-panel/assets/MarkdownRenderer-RQ1HbTY5.js +0 -1
  184. package/src/assets/web-panel/assets/devWarning-Cwuuqc_f.js +0 -1
  185. package/src/assets/web-panel/assets/index-BkTk-zJK.js +0 -1
  186. package/src/assets/web-panel/assets/index-C-BSTEhe.js +0 -1
@@ -0,0 +1,450 @@
1
+ /**
2
+ * Process Execution Broker — M1+M2+M3+M4+M5 集成
3
+ * 对应文档 §2.1 四层架构 Layer 1
4
+ *
5
+ * 统一拦截所有子进程执行:
6
+ * - M1: 所有子进程唯一入口,权限检查
7
+ * - M2: 沙箱分发(shell/sdk/jsii)
8
+ * - M3: 集成W3C trace context自动传播
9
+ * - M4: 自动写入Runtime Provenance Ledger (RPL)
10
+ * - M5: Hooks v2事件发射
11
+ */
12
+
13
+ // 直接导入原生child_process,避免递归
14
+ import {
15
+ spawn as nativeSpawn,
16
+ spawnSync as nativeSpawnSync,
17
+ exec as nativeExec,
18
+ execSync as nativeExecSync,
19
+ execFile as nativeExecFile,
20
+ execFileSync as nativeExecFileSync,
21
+ fork as nativeFork,
22
+ } from "node:child_process";
23
+ import { EventEmitter } from "node:events";
24
+ import crypto from "node:crypto";
25
+ import os from "node:os";
26
+ import path from "node:path";
27
+ import fs from "node:fs";
28
+
29
+ // 延迟导入避免循环依赖
30
+ let _traceCtx = null;
31
+ let _rpl = null;
32
+ let _hooksV2 = null;
33
+ let _ipcBus = null;
34
+
35
+ function getTraceCtx() {
36
+ if (!_traceCtx) {
37
+ try {
38
+ _traceCtx = require("../execution-trace/trace-context.js");
39
+ } catch {
40
+ _traceCtx = null;
41
+ }
42
+ }
43
+ return _traceCtx;
44
+ }
45
+
46
+ function getRpl() {
47
+ if (!_rpl) {
48
+ try {
49
+ _rpl = require("../runtime-provenance-ledger.js");
50
+ } catch {
51
+ _rpl = null;
52
+ }
53
+ }
54
+ return _rpl;
55
+ }
56
+
57
+ function getHooksV2() {
58
+ if (!_hooksV2) {
59
+ try {
60
+ _hooksV2 = require("../hooks-v2-runtime.js");
61
+ } catch {
62
+ _hooksV2 = null;
63
+ }
64
+ }
65
+ return _hooksV2;
66
+ }
67
+
68
+ class ProcessExecutionBroker extends EventEmitter {
69
+ constructor() {
70
+ super();
71
+ this._auditLog = [];
72
+ this._permissionState = new Map();
73
+ this._defaultTimeout = 300000;
74
+ this._blocked = new Set(["rm -rf /", "format c:", "del /f /s /q *"]);
75
+ this._stats = { totalSpawned: 0, allowed: 0, denied: 0, byOrigin: {} };
76
+ this._logPath = path.join(
77
+ os.homedir(),
78
+ ".chainlesschain",
79
+ "logs",
80
+ "process-audit.log",
81
+ );
82
+ this._ensureLogDir();
83
+ this._loadPermissions();
84
+ }
85
+
86
+ _ensureLogDir() {
87
+ try {
88
+ fs.mkdirSync(path.dirname(this._logPath), { recursive: true });
89
+ } catch {}
90
+ }
91
+
92
+ _loadPermissions() {
93
+ this._permissionState.set("shell:default", "prompt");
94
+ this._permissionState.set("background:default", "allow");
95
+ this._permissionState.set("plugin:default", "deny");
96
+ this._permissionState.set("mcp:default", "prompt");
97
+ this._permissionState.set("agent:default", "prompt");
98
+ this._permissionState.set("installer:default", "allow");
99
+ this._permissionState.set("lsp:default", "allow");
100
+ }
101
+
102
+ _checkPermission(origin, command) {
103
+ const key = `${origin}:${command}`;
104
+ if (this._permissionState.has(key)) return this._permissionState.get(key);
105
+ const wildcard = `${origin}:default`;
106
+ if (this._permissionState.has(wildcard))
107
+ return this._permissionState.get(wildcard);
108
+ return "prompt";
109
+ }
110
+
111
+ _isDangerousCommand(command) {
112
+ if (typeof command !== "string") return false;
113
+ const lower = command.toLowerCase();
114
+ for (const blocked of this._blocked) {
115
+ if (lower.includes(blocked)) return true;
116
+ }
117
+ if (/rm\s+-rf\s+~/.test(lower)) return true;
118
+ if (/del\s+\/[fsq].*windows/i.test(lower)) return true;
119
+ return false;
120
+ }
121
+
122
+ _recordAudit(entry) {
123
+ this._auditLog.push(entry);
124
+ if (this._auditLog.length > 10000) this._auditLog.shift();
125
+ this._stats.totalSpawned++;
126
+ if (
127
+ entry.permissionDecision === "allow" ||
128
+ entry.permissionDecision === "elevated"
129
+ ) {
130
+ this._stats.allowed++;
131
+ } else {
132
+ this._stats.denied++;
133
+ }
134
+ this._stats.byOrigin[entry.origin] =
135
+ (this._stats.byOrigin[entry.origin] || 0) + 1;
136
+ try {
137
+ fs.appendFileSync(this._logPath, JSON.stringify(entry) + "\n");
138
+ } catch {}
139
+ this.emit("spawn", entry);
140
+ }
141
+
142
+ _sanitizeOptions(options) {
143
+ if (!options) return {};
144
+ const safe = { ...options };
145
+ if (process.platform === "win32" && safe.shell === true) {
146
+ safe.windowsHide = true;
147
+ }
148
+ return safe;
149
+ }
150
+
151
+ _getTraceContext() {
152
+ const traceCtx = getTraceCtx();
153
+ if (traceCtx && traceCtx.activeContext) {
154
+ return traceCtx.activeContext.value || null;
155
+ }
156
+ return null;
157
+ }
158
+
159
+ _writeRplEntry(auditEntry, status = "started", error = null) {
160
+ const rpl = getRpl();
161
+ if (!rpl || !rpl.default) return;
162
+ try {
163
+ const traceCtx = this._getTraceContext();
164
+ rpl.default.append(
165
+ {
166
+ kind: "process.execution",
167
+ component: auditEntry.origin,
168
+ action: "spawn",
169
+ artifactId: auditEntry.executionId,
170
+ artifactType: "subprocess",
171
+ inputs: {
172
+ command: auditEntry.command,
173
+ args: auditEntry.args,
174
+ cwd: auditEntry.cwd,
175
+ },
176
+ outputs:
177
+ status === "completed"
178
+ ? { exitCode: auditEntry.exitCode || 0 }
179
+ : error
180
+ ? { error: error.message }
181
+ : {},
182
+ permissions: {
183
+ decision: auditEntry.permissionDecision,
184
+ policy: auditEntry.policy,
185
+ scope: auditEntry.scope,
186
+ },
187
+ traceId:
188
+ traceCtx?.traceId || auditEntry.traceId || `trace-${Date.now()}`,
189
+ parentSpanId: traceCtx?.spanId || null,
190
+ trustLevel:
191
+ auditEntry.permissionDecision === "deny" ? "untrusted" : "trusted",
192
+ },
193
+ auditEntry.origin,
194
+ );
195
+ } catch (e) {}
196
+ }
197
+
198
+ _emitHooksEvent(event, data) {
199
+ const hooks = getHooksV2();
200
+ if (!hooks || !hooks.hooksV2) return;
201
+ try {
202
+ hooks.hooksV2.emit(event, data);
203
+ } catch {}
204
+ }
205
+
206
+ spawn(command, args, options = {}) {
207
+ const executionId = crypto.randomUUID();
208
+ const startTime = Date.now();
209
+ const origin = options.origin || "unknown";
210
+ const cwd = options.cwd || process.cwd();
211
+ const scope = options.scope || "default";
212
+ const policy = options.policy || this._checkPermission(origin, command);
213
+ const isDangerous = this._isDangerousCommand(
214
+ typeof command === "string" ? command : command?.toString?.() || "",
215
+ );
216
+ let decision = policy;
217
+ if (isDangerous && policy !== "deny") decision = "deny";
218
+ if (options.forceAllow) decision = "elevated";
219
+
220
+ const traceCtx = this._getTraceContext();
221
+ const auditEntry = {
222
+ executionId,
223
+ traceId: traceCtx?.traceId || null,
224
+ origin,
225
+ scope,
226
+ command,
227
+ args: args || [],
228
+ cwd,
229
+ startTime,
230
+ permissionDecision: decision,
231
+ policy,
232
+ isDangerous,
233
+ shell: !!options.shell,
234
+ pid: null,
235
+ exitCode: null,
236
+ endTime: null,
237
+ durationMs: null,
238
+ };
239
+
240
+ if (decision === "deny" || decision === "prompt") {
241
+ auditEntry.deniedReason = isDangerous
242
+ ? "dangerous_command"
243
+ : `policy_${decision}`;
244
+ auditEntry.endTime = Date.now();
245
+ auditEntry.durationMs = 0;
246
+ this._recordAudit(auditEntry);
247
+ this._writeRplEntry(
248
+ auditEntry,
249
+ "denied",
250
+ new Error(auditEntry.deniedReason),
251
+ );
252
+ this._emitHooksEvent("tool:end", {
253
+ executionId,
254
+ success: false,
255
+ error: auditEntry.deniedReason,
256
+ component: origin,
257
+ });
258
+ const err = new Error(
259
+ `Process spawn denied: ${auditEntry.deniedReason} (origin=${origin}, command=${command})`,
260
+ );
261
+ err.auditEntry = auditEntry;
262
+ throw err;
263
+ }
264
+
265
+ // 传播traceparent环境变量
266
+ const spawnOpts = this._sanitizeOptions(options);
267
+ if (traceCtx) {
268
+ spawnOpts.env = { ...(spawnOpts.env || process.env) };
269
+ spawnOpts.env.TRACEPARENT = traceCtx.traceparent;
270
+ }
271
+
272
+ // Use native spawn from _native (set by patch-child-process.js)
273
+ const nativeSpawn = this._native?.spawn || nativeSpawn;
274
+ const proc = nativeSpawn(command, args, spawnOpts);
275
+ auditEntry.pid = proc.pid;
276
+ this._recordAudit(auditEntry);
277
+ this._writeRplEntry(auditEntry, "started");
278
+ this._emitHooksEvent("tool:start", {
279
+ executionId,
280
+ toolName: origin,
281
+ command,
282
+ args,
283
+ cwd,
284
+ pid: proc.pid,
285
+ component: origin,
286
+ });
287
+
288
+ proc.on("exit", (code, signal) => {
289
+ const endTime = Date.now();
290
+ auditEntry.exitCode = code;
291
+ auditEntry.signal = signal;
292
+ auditEntry.endTime = endTime;
293
+ auditEntry.durationMs = endTime - startTime;
294
+ this._writeRplEntry(auditEntry, "completed");
295
+ this._emitHooksEvent("tool:end", {
296
+ executionId,
297
+ success: code === 0,
298
+ exitCode: code,
299
+ signal,
300
+ durationMs: auditEntry.durationMs,
301
+ component: origin,
302
+ });
303
+ this.emit("exit", auditEntry);
304
+ });
305
+ proc.on("error", (err) => {
306
+ auditEntry.error = err.message;
307
+ auditEntry.endTime = Date.now();
308
+ auditEntry.durationMs = auditEntry.endTime - startTime;
309
+ this._writeRplEntry(auditEntry, "error", err);
310
+ this._emitHooksEvent("tool:end", {
311
+ executionId,
312
+ success: false,
313
+ error: err.message,
314
+ component: origin,
315
+ });
316
+ this.emit("error", auditEntry);
317
+ });
318
+ return proc;
319
+ }
320
+
321
+ spawnSync(command, args, options = {}) {
322
+ const executionId = crypto.randomUUID();
323
+ const startTime = Date.now();
324
+ const origin = options.origin || "unknown";
325
+ const cwd = options.cwd || process.cwd();
326
+ const scope = options.scope || "default";
327
+ const policy = options.policy || this._checkPermission(origin, command);
328
+ const isDangerous = this._isDangerousCommand(
329
+ typeof command === "string" ? command : command?.toString?.() || "",
330
+ );
331
+ let decision = policy;
332
+ if (isDangerous && policy !== "deny") decision = "deny";
333
+ if (options.forceAllow) decision = "elevated";
334
+
335
+ const traceCtx = this._getTraceContext();
336
+ const auditEntry = {
337
+ executionId,
338
+ traceId: traceCtx?.traceId || null,
339
+ origin,
340
+ scope,
341
+ command,
342
+ args: args || [],
343
+ cwd,
344
+ startTime,
345
+ permissionDecision: decision,
346
+ policy,
347
+ isDangerous,
348
+ shell: !!options.shell,
349
+ sync: true,
350
+ };
351
+
352
+ if (decision === "deny" || decision === "prompt") {
353
+ auditEntry.deniedReason = isDangerous
354
+ ? "dangerous_command"
355
+ : `policy_${decision}`;
356
+ auditEntry.endTime = Date.now();
357
+ auditEntry.durationMs = 0;
358
+ this._recordAudit(auditEntry);
359
+ this._writeRplEntry(
360
+ auditEntry,
361
+ "denied",
362
+ new Error(auditEntry.deniedReason),
363
+ );
364
+ const err = new Error(
365
+ `Process spawnSync denied: ${auditEntry.deniedReason}`,
366
+ );
367
+ err.auditEntry = auditEntry;
368
+ throw err;
369
+ }
370
+
371
+ const spawnOpts = this._sanitizeOptions(options);
372
+ if (traceCtx) {
373
+ spawnOpts.env = { ...(spawnOpts.env || process.env) };
374
+ spawnOpts.env.TRACEPARENT = traceCtx.traceparent;
375
+ }
376
+
377
+ const nativeSpawnSync = this._native?.spawnSync || nativeSpawnSync;
378
+ try {
379
+ const result = nativeSpawnSync(command, args, spawnOpts);
380
+ auditEntry.exitCode = result.status;
381
+ auditEntry.endTime = Date.now();
382
+ auditEntry.durationMs = auditEntry.endTime - startTime;
383
+ this._recordAudit(auditEntry);
384
+ this._writeRplEntry(auditEntry, "completed");
385
+ return result;
386
+ } catch (err) {
387
+ auditEntry.error = err.message;
388
+ auditEntry.endTime = Date.now();
389
+ auditEntry.durationMs = auditEntry.endTime - startTime;
390
+ this._recordAudit(auditEntry);
391
+ this._writeRplEntry(auditEntry, "error", err);
392
+ throw err;
393
+ }
394
+ }
395
+
396
+ exec(command, options, callback) {
397
+ const opts = typeof options === "function" ? {} : options;
398
+ const cb = typeof options === "function" ? options : callback;
399
+ return this.spawn(command, [], {
400
+ ...opts,
401
+ shell: true,
402
+ origin: opts.origin || "shell:exec",
403
+ });
404
+ }
405
+
406
+ execSync(command, options = {}) {
407
+ const spawnOpts = {
408
+ ...options,
409
+ shell: true,
410
+ origin: options.origin || "shell:execSync",
411
+ };
412
+ return this.spawnSync(command, [], spawnOpts);
413
+ }
414
+
415
+ execFile(file, args, options, callback) {
416
+ return this.spawn(file, args, options || {});
417
+ }
418
+
419
+ execFileSync(file, args, options = {}) {
420
+ return this.spawnSync(file, args, options);
421
+ }
422
+
423
+ fork(modulePath, args, options = {}) {
424
+ return this.spawn(process.execPath, [modulePath, ...(args || [])], {
425
+ ...options,
426
+ origin: options.origin || "fork",
427
+ });
428
+ }
429
+
430
+ setPermission(origin, command, decision) {
431
+ const key = command ? `${origin}:${command}` : `${origin}:default`;
432
+ this._permissionState.set(key, decision);
433
+ }
434
+
435
+ getStats() {
436
+ return { ...this._stats };
437
+ }
438
+ getAuditLog(limit = 100) {
439
+ return this._auditLog.slice(-limit);
440
+ }
441
+ flushAuditLog() {
442
+ const log = [...this._auditLog];
443
+ this._auditLog = [];
444
+ return log;
445
+ }
446
+ }
447
+
448
+ const broker = new ProcessExecutionBroker();
449
+ export { broker as executionBroker };
450
+ export default broker;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Monkey-patch node:child_process to route ALL spawn/exec calls through ExecutionBroker (M1)
3
+ * This runs at CLI startup, before any other imports, ensuring every subprocess is audited
4
+ */
5
+ import { createRequire } from "node:module";
6
+ const require = createRequire(import.meta.url);
7
+
8
+ // Import ExecutionBroker singleton
9
+ const { executionBroker } = require("./index.js");
10
+
11
+ // Get the REAL native child_process module (unpatched, from Node.js internals)
12
+ const nativeCp = require("node:child_process");
13
+
14
+ // Replace all exported functions with broker-wrapped versions
15
+ // The broker already imports native methods directly, so NO RECURSION here
16
+ nativeCp.spawn = function patchedSpawn(command, args, options) {
17
+ return executionBroker.spawn(command, args, options);
18
+ };
19
+
20
+ nativeCp.spawnSync = function patchedSpawnSync(command, args, options) {
21
+ return executionBroker.spawnSync(command, args, options);
22
+ };
23
+
24
+ nativeCp.exec = function patchedExec(command, options, callback) {
25
+ return executionBroker.exec(command, options, callback);
26
+ };
27
+
28
+ nativeCp.execSync = function patchedExecSync(command, options) {
29
+ return executionBroker.execSync(command, options);
30
+ };
31
+
32
+ nativeCp.execFile = function patchedExecFile(file, args, options, callback) {
33
+ return executionBroker.execFile(file, args, options, callback);
34
+ };
35
+
36
+ nativeCp.execFileSync = function patchedExecFileSync(file, args, options) {
37
+ return executionBroker.execFileSync(file, args, options);
38
+ };
39
+
40
+ nativeCp.fork = function patchedFork(modulePath, args, options) {
41
+ return executionBroker.fork(modulePath, args, options);
42
+ };
43
+
44
+ // Also patch child_process for CommonJS require
45
+ const cpModule = require.cache[require.resolve("node:child_process")];
46
+ if (cpModule && cpModule.exports) {
47
+ cpModule.exports = nativeCp;
48
+ }
49
+
50
+ export default executionBroker;