chainlesschain 0.162.177 → 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.
- package/README.md +10 -0
- package/package.json +1 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-DT-VPWuN.js → AIOps-DRftcSue.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DyOreOVN.js → ActionButton-BFvUaMKR.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DslNsKux.js → Analytics-C0-Rru4P.js} +3 -3
- package/src/assets/web-panel/assets/AppLayout-bx-BCljj.js +9 -0
- package/src/assets/web-panel/assets/{Artifacts-DoaAtEcY.js → Artifacts-DAJ8B3Un.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DPG3WdJ9.js → Audit-hOk4L1lr.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-C_JO6R5G.js → BackgroundAgents-3pbDpM9z.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-Cv3BooyX.js → Backup-BtziGDn9.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-D2uQXWu-.js → BaseInput-kmshphJ3.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-B4Vczyf3.js → Chat-d7tGSosA.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-p-_PBpX_.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-qTgk4VeP.js → Checkbox-C4Eh4Tz5.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DlLWcIzj.js → Codegen-r7gmhZyA.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DNO73qp7.js → Col-U7mDaGlL.js} +1 -1
- package/src/assets/web-panel/assets/{Community-vRDNpc4j.js → Community-Bpu8aH1T.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-CEWtIXni.js → Compact-CHb2XBJe.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-KgYC9Fxi.js → Compliance-Cn_r4dey.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-zj5wvkpT.js → Cowork-CdMWfDcz.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-BLDoCozU.js → Cron-BtnREHWy.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BYnff4VY.js → Crosschain-BKI9TSzr.js} +1 -1
- package/src/assets/web-panel/assets/{DID-C75VFsVm.js → DID-pkNubzzJ.js} +2 -2
- package/src/assets/web-panel/assets/Dashboard-1rrz1snN.js +3 -0
- package/src/assets/web-panel/assets/{Dropdown-B5dbO4Kx.js → Dropdown-DLyFVxDc.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BDipZtHJ.js → EmailListRenderer-CtUWfYVq.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-DmIzt8jj.js → FamilyGuardDashboard-B8eX2Qe4.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-D9QOS-uW.js → Federation-D8lsDGus.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-B47HRwAm.js → FormItemContext-CRYt_aIw.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-3R4mXmgV.js → GenericCardRenderer-ClKzY8_N.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DrNXZf1C.js → Git-BXj5Dney.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BGd7JR98.js → Governance-Cm-I8RMz.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-D-2he1ed.js → Inference-CPvbhvgt.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-C0sHIbK5.js → KnowledgeGraph-sYNDZaoi.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-DiBQO-jL.js → Logs-BZY_3CRZ.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-DL_5eV2D.js → MarkdownRenderer-up0BW6pv.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-VR59OdrC.js → Marketplace-C5MEJ2Qe.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DrPzwSd3.js → McpTools-ihdrn43I.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-CBgKALwQ.js → Memory-Br8bPMlh.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-pQ9Tn-Mn.js → MobileBridge-BNntgrYW.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-mASB6jyj.js → MobileProjects-BdV915mw.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-DTMgE7HC.js → Mtc-A3wDmlqL.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-CwTnCtiL.js → MtcAudit-CF-mBLWM.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-ngm6WU8f.js → Multisig-Iy2k_MSo.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-4YO4Qww9.js → NLProgramming-kk0W7HUb.js} +1 -1
- package/src/assets/web-panel/assets/Notes-B5u5t_4S.js +7 -0
- package/src/assets/web-panel/assets/{NotificationSettings-r2H8yPKb.js → NotificationSettings-BN0POf6_.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-CHkSUrXB.js +1 -0
- package/src/assets/web-panel/assets/{Organization-DrO7jRWS.js → Organization-DwWQESuN.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-Cnwu4i4t.js → Overflow-DG6klrcC.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-zi-cDwA_.js → P2P-BwJcKkgZ.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-DBEryDv7.js → PdhVaultBrowser-BwOHG0in.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-lqXK2C3x.js → Permissions-CGMXe4TX.js} +4 -4
- package/src/assets/web-panel/assets/PersonalDataHub-ziYqg7-A.js +8 -0
- package/src/assets/web-panel/assets/{Pipeline-Kep5KAGW.js → Pipeline-BzJfeoGt.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-CHdvOAh1.js → Privacy-DLh3Bblx.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BhKfdwe9.js → ProjectInit-USVWW36c.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-Yavk9K8A.js → ProjectSettings-CiiOn62h.js} +2 -2
- package/src/assets/web-panel/assets/Projects-6V-PNmcA.js +1 -0
- package/src/assets/web-panel/assets/{Providers-Bfym6SQn.js → Providers-CBPWWzpu.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-CLSQcrlR.js → QrScannerModal-QVwoRUq3.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-VPa2WKQN.js → QuickAsk-CXnR-2Vn.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CGXR8jVU.js → Recommend-ClaNzjmF.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-C_20YfMB.js → RemoteSession-C3rGw8vJ.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-awZh68UV.js → Reputation-Ci-OWAoP.js} +1 -1
- package/src/assets/web-panel/assets/{Row-Ctb4oiYN.js → Row-DRhAwXOS.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-D3sdjvUV.js → RssFeed-BQLJQ2_y.js} +3 -3
- package/src/assets/web-panel/assets/{Search-C-zfA4kT.js → Search-QQUpkfFd.js} +1 -1
- package/src/assets/web-panel/assets/{Security-D9XlmHA3.js → Security-DdXKzuKT.js} +4 -4
- package/src/assets/web-panel/assets/{Services-C3UKnr41.js → Services-x2Zh62Qd.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-BQxagZfF.js → Skeleton-GdY4KwRz.js} +1 -1
- package/src/assets/web-panel/assets/Skills-Bv4tY1Fd.js +1 -0
- package/src/assets/web-panel/assets/{Sla-DveENvek.js → Sla-C3QnM-11.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-BFjXLNgF.js → SpeechSettings-Bl3ytvmI.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BpHgbaP9.js → SyncSettings-Wp9IwTsP.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-CF3rIrDe.js +1 -0
- package/src/assets/web-panel/assets/{Templates-DEiaoyve.js → Templates-CGfvVVM9.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-ITg774nY.js → Tenant-CVXmwQ3U.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-D3ZBcvnb.js → Terminal-bvwrt03E.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-BsLU6JjU.js → TimelineRenderer-D0g74KhH.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-Cb5Pquc9.js → Tokens-BH4IwzlT.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-Dwfy-m9N.js → Trigger-DJOpM533.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-CnlSRGG0.js → Trust-B43EPRLr.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-Y4TlvKVo.js → UkeySign-BmBFG-em.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BpKLtTTO.js → VideoEditing-n9oJwB8k.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-LLBzIq8x.js → Wallet-D5QeivHp.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-BeSRiusP.js → WebAuthn-DcNy7igO.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-BK_l1tXO.js → WorkflowEditor-BVjc7-5-.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DYd-X7Wg.js → chat-Dy5Tfj3m.js} +1 -1
- package/src/assets/web-panel/assets/{colors-C9uip71j.js → colors-C4c2CNZU.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-JBrfjUP6.js → compact-item-DPa3O5vN.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-D03fbuiq.js → createContext-TLcfNA6_.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BAwdDA_5.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DLQOR6l-.js → hasIn-D41LVFkp.js} +1 -1
- package/src/assets/web-panel/assets/{index-rIxxfdTN.js → index-0oevYjfT.js} +1 -1
- package/src/assets/web-panel/assets/{index-CChaISMb.js → index-388pLGJ1.js} +1 -1
- package/src/assets/web-panel/assets/{index-BfOs_bmg.js → index-B8nLBZbv.js} +3 -3
- package/src/assets/web-panel/assets/{index-D-1SqEpQ.js → index-BPTGAjee.js} +1 -1
- package/src/assets/web-panel/assets/{index-BYv-LWdy.js → index-BPtrOBmW.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cpn19c9k.js → index-BQiIxHBy.js} +1 -1
- package/src/assets/web-panel/assets/{index-BpYKLrUT.js → index-BSM1cHVK.js} +1 -1
- package/src/assets/web-panel/assets/{index-CS63r8h3.js → index-BYPr9fkz.js} +1 -1
- package/src/assets/web-panel/assets/{index-Q7mmL6w4.js → index-BsQ7Ev6i.js} +1 -1
- package/src/assets/web-panel/assets/{index-SO6lgMg0.js → index-Btk9qLL2.js} +1 -1
- package/src/assets/web-panel/assets/{index-iahNhZwm.js → index-BvmziZSG.js} +1 -1
- package/src/assets/web-panel/assets/{index-BnQgRjsm.js → index-BvopLC_T.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ba-Ps_AJ.js → index-C7xhTVyP.js} +1 -1
- package/src/assets/web-panel/assets/{index-BuNFCZCx.js → index-CNk_ZooP.js} +1 -1
- package/src/assets/web-panel/assets/{index-CL0ixCxk.js → index-CQrEHoOG.js} +1 -1
- package/src/assets/web-panel/assets/{index-CChQBM1d.js → index-CSxex23J.js} +1 -1
- package/src/assets/web-panel/assets/{index-5YN7F5bO.js → index-CVjgm992.js} +1 -1
- package/src/assets/web-panel/assets/{index-CwoDpKzW.js → index-CWK4zOPe.js} +1 -1
- package/src/assets/web-panel/assets/{index-BcBZwlnG.js → index-CX0VsoP4.js} +1 -1
- package/src/assets/web-panel/assets/{index-B46YcgsV.js → index-CXl0YPNG.js} +1 -1
- package/src/assets/web-panel/assets/{index-l08afIbV.js → index-Cip7LWml.js} +1 -1
- package/src/assets/web-panel/assets/{index-6GuLRpBQ.js → index-Cq_hlWNt.js} +1 -1
- package/src/assets/web-panel/assets/{index-DYLZY4uh.js → index-CzZ49YZL.js} +1 -1
- package/src/assets/web-panel/assets/{index-B0X76LjX.js → index-D2Nkivlm.js} +1 -1
- package/src/assets/web-panel/assets/{index-BdH9l8wl.js → index-DBUgRs4D.js} +1 -1
- package/src/assets/web-panel/assets/index-DEjVkdzq.js +1 -0
- package/src/assets/web-panel/assets/{index-D4UY5Z60.js → index-DNsBj2Ob.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ce0Bf1YF.js → index-Di4X8cfI.js} +1 -1
- package/src/assets/web-panel/assets/{index-ByHO3SqZ.js → index-DljFsVGI.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2zmOsyD.js → index-Korc3QIe.js} +1 -1
- package/src/assets/web-panel/assets/index-LMOc5xrS.js +1 -0
- package/src/assets/web-panel/assets/{index-BNCdRmWf.js → index-MKZDje0H.js} +1 -1
- package/src/assets/web-panel/assets/{index-D8KvuDz0.js → index-OHAfRu_3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaokIHt3.js → index-WEJr8PL5.js} +1 -1
- package/src/assets/web-panel/assets/{index-CILVyK3b.js → index-WinCp6du.js} +1 -1
- package/src/assets/web-panel/assets/{index-CVZWiUE_.js → index-Yjr6cqSK.js} +1 -1
- package/src/assets/web-panel/assets/{index-CqWk1FLG.js → index-iQ6gtFih.js} +1 -1
- package/src/assets/web-panel/assets/{index-DNMAAUVk.js → index-pt3s7yvV.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ck17i0OD.js → index-tQ3igERQ.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CG9z1c6w.js → initDefaultProps-BFZu87WZ.js} +1 -1
- package/src/assets/web-panel/assets/{motion-B1Ky7Zff.js → motion-DJIo7qvt.js} +1 -1
- package/src/assets/web-panel/assets/{move-DME8X2P1.js → move-Cfr5qknL.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-cuJYSWB7.js → mtc-parser-Bgc-OadH.js} +1 -1
- package/src/assets/web-panel/assets/{omit-UI_EE0uZ.js → omit-X3WI-TNp.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-BIoE_Z_V.js → pickAttrs-pJhU9IxK.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-B48-9HKN.js → placementArrow-BNg_Vj3T.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-D7x_GDgD.js → responsiveObserve-TeSEGQ5-.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DjzC5_7m.js → slide-D_t_P0bv.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-C6BIymhh.js → statusUtils-DrrIMwAT.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-B4dGrdD9.js → styleChecker-BjZCuFRm.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-Bken4aNE.js → useFlexGapSupport-rTFdlqdQ.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-BMlqECqv.js → useFs-BidCpfLX.js} +1 -1
- package/src/assets/web-panel/assets/usePersonalDataHub-C5mHttA9.js +1 -0
- package/src/assets/web-panel/assets/{vnode-CKJQmxa0.js → vnode-BrbcRiHZ.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CaZunuau.js → zoom-PISX7AkR.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/__tests__/hub-wechat.test.js +45 -0
- package/src/commands/background-session.js +5 -2
- package/src/commands/context.js +33 -1
- package/src/commands/hub.js +473 -39
- package/src/commands/init.js +212 -110
- package/src/commands/llm.js +22 -6
- package/src/commands/skill.js +11 -1
- package/src/data/changelog.json +76 -270
- package/src/gateways/ws/personal-data-hub-protocol.js +22 -2
- package/src/harness/golden-transcript.js +3 -0
- package/src/index.js +18 -7
- package/src/lib/approval-authority-store.js +891 -0
- package/src/lib/background-interaction-resolver.js +399 -54
- package/src/lib/background-session-transport.js +3 -1
- package/src/lib/context-breakdown.js +82 -3
- package/src/lib/event-runtime-host.js +225 -0
- package/src/lib/event-runtime-store.js +102 -21
- package/src/lib/event-runtime-worker.js +70 -2
- package/src/lib/hooks-v2-producers.js +33 -8
- package/src/lib/hooks-v2-runtime.js +360 -40
- package/src/lib/interaction-adapter.js +66 -0
- package/src/lib/operation-fingerprint.js +107 -2
- package/src/lib/pdh-dedicated-batch-collectors.js +124 -0
- package/src/lib/personal-data-hub-wiring.js +327 -52
- package/src/lib/process-execution-broker/credential-agent.js +954 -111
- package/src/lib/process-execution-broker/index.js +369 -85
- package/src/lib/process-execution-broker/platform-sandbox.js +320 -140
- package/src/lib/provider-http-error.js +94 -0
- package/src/lib/remote-approval-bridge.js +222 -26
- package/src/lib/side-effect-ledger-store.js +65 -14
- package/src/lib/skill-loader.js +215 -12
- package/src/lib/skill-process-broker.js +15 -1
- package/src/lib/sub-agent-context.js +42 -0
- package/src/lib/turn-binding-store.js +64 -15
- package/src/lib/turn-binding.js +85 -16
- package/src/repl/agent-repl.js +40 -6
- package/src/repl/remote-approval.js +13 -13
- package/src/repl/repl-turn-binding.js +46 -16
- package/src/runtime/agent-core.js +286 -35
- package/src/runtime/coding-agent-contract-shared.cjs +16 -0
- package/src/runtime/headless-runner.js +147 -34
- package/src/runtime/headless-stream.js +147 -7
- package/src/workers/background-agent-worker.js +70 -38
- package/src/assets/web-panel/assets/AppLayout-BNJJAYME.js +0 -9
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DE6reP99.js +0 -1
- package/src/assets/web-panel/assets/Dashboard-C4Gutni2.js +0 -3
- package/src/assets/web-panel/assets/Notes-DP1k45mF.js +0 -7
- package/src/assets/web-panel/assets/OrderTableRenderer-CoM_Zw0J.js +0 -1
- package/src/assets/web-panel/assets/PersonalDataHub-b63T3HJM.js +0 -9
- package/src/assets/web-panel/assets/Projects-CN8E_5Mq.js +0 -1
- package/src/assets/web-panel/assets/Skills-q6eb6KPZ.js +0 -1
- package/src/assets/web-panel/assets/Tasks-DvepRb8-.js +0 -1
- package/src/assets/web-panel/assets/devWarning-B8LQ8leS.js +0 -1
- package/src/assets/web-panel/assets/index-Bh8BPtqR.js +0 -1
- package/src/assets/web-panel/assets/index-CeVrHLzZ.js +0 -1
- package/src/assets/web-panel/assets/usePersonalDataHub-DLdrfmMa.js +0 -1
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
*
|
|
5
5
|
* 统一拦截所有子进程执行:
|
|
6
6
|
* - M1: 所有子进程唯一入口,权限检查
|
|
7
|
-
* - **P0-1**:
|
|
7
|
+
* - **P0-1**: 可审计的平台执行计划(macOS Seatbelt / Linux prlimit;
|
|
8
|
+
* Windows 原生 Job Object 未实现时明确报告 unavailable)
|
|
8
9
|
* - **P0-1**: 凭据代理 default-on(secrets 永远不裸传给子进程)
|
|
9
10
|
* - M3: 集成W3C trace context自动传播
|
|
10
11
|
* - M4: 自动写入Runtime Provenance Ledger (RPL)
|
|
@@ -25,7 +26,7 @@ import { EventEmitter } from "node:events";
|
|
|
25
26
|
import crypto from "node:crypto";
|
|
26
27
|
import os from "node:os";
|
|
27
28
|
import path from "node:path";
|
|
28
|
-
import fs from "node:fs";
|
|
29
|
+
import * as fs from "node:fs";
|
|
29
30
|
import { createRequire } from "node:module";
|
|
30
31
|
|
|
31
32
|
const require = createRequire(import.meta.url);
|
|
@@ -110,6 +111,10 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
110
111
|
// plugin path use the same switches as the general broker path.
|
|
111
112
|
this._credentialAgentEnabled = true;
|
|
112
113
|
this._platformSandboxEnabled = true;
|
|
114
|
+
this._sandboxAdapter = {
|
|
115
|
+
applySandbox: _applySandbox,
|
|
116
|
+
postSpawnSandbox: _postSpawnSandbox,
|
|
117
|
+
};
|
|
113
118
|
|
|
114
119
|
this._ensureLogDir();
|
|
115
120
|
this._loadPermissions();
|
|
@@ -118,7 +123,9 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
118
123
|
_ensureLogDir() {
|
|
119
124
|
try {
|
|
120
125
|
fs.mkdirSync(path.dirname(this._logPath), { recursive: true });
|
|
121
|
-
} catch {
|
|
126
|
+
} catch {
|
|
127
|
+
// Audit persistence is best-effort; in-memory audit remains available.
|
|
128
|
+
}
|
|
122
129
|
}
|
|
123
130
|
|
|
124
131
|
_loadPermissions() {
|
|
@@ -167,7 +174,9 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
167
174
|
(this._stats.byOrigin[entry.origin] || 0) + 1;
|
|
168
175
|
try {
|
|
169
176
|
fs.appendFileSync(this._logPath, JSON.stringify(entry) + "\n");
|
|
170
|
-
} catch {
|
|
177
|
+
} catch {
|
|
178
|
+
// Audit persistence is best-effort; the in-memory entry is retained.
|
|
179
|
+
}
|
|
171
180
|
this.emit("spawn", entry);
|
|
172
181
|
}
|
|
173
182
|
|
|
@@ -180,6 +189,283 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
180
189
|
return safe;
|
|
181
190
|
}
|
|
182
191
|
|
|
192
|
+
_sandboxStrictEnabled() {
|
|
193
|
+
return process.env.CC_SANDBOX_STRICT === "1";
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
_sandboxDisabledByEnvironment() {
|
|
197
|
+
return process.env.CC_SANDBOX_DISABLE === "1";
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
_sandboxUnavailablePlan(command, args, options, reason) {
|
|
201
|
+
return {
|
|
202
|
+
contractVersion: 1,
|
|
203
|
+
applied: false,
|
|
204
|
+
platform: process.platform,
|
|
205
|
+
profile: "default",
|
|
206
|
+
command,
|
|
207
|
+
args: [...(args || [])],
|
|
208
|
+
options: { ...options },
|
|
209
|
+
enforcement: null,
|
|
210
|
+
reason,
|
|
211
|
+
postSpawn: { required: false, mode: "none" },
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
_sandboxError(reason, message = reason) {
|
|
216
|
+
const error = new Error(message);
|
|
217
|
+
error.code = "ERR_PROCESS_SANDBOX";
|
|
218
|
+
error.sandboxReason = reason;
|
|
219
|
+
return error;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
_validateSandboxPlan(plan) {
|
|
223
|
+
if (!plan || typeof plan !== "object") {
|
|
224
|
+
throw this._sandboxError(
|
|
225
|
+
"invalid_sandbox_plan",
|
|
226
|
+
"Sandbox adapter returned no spawn plan",
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
if (plan.contractVersion !== 1) {
|
|
230
|
+
throw this._sandboxError(
|
|
231
|
+
"invalid_sandbox_plan",
|
|
232
|
+
"Sandbox spawn plan contractVersion must be 1",
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
if (typeof plan.applied !== "boolean") {
|
|
236
|
+
throw this._sandboxError(
|
|
237
|
+
"invalid_sandbox_plan",
|
|
238
|
+
"Sandbox spawn plan is missing applied:boolean",
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
if (typeof plan.command !== "string" || !Array.isArray(plan.args)) {
|
|
242
|
+
throw this._sandboxError(
|
|
243
|
+
"invalid_sandbox_plan",
|
|
244
|
+
"Sandbox spawn plan must provide command and args",
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
if (!plan.options || typeof plan.options !== "object") {
|
|
248
|
+
throw this._sandboxError(
|
|
249
|
+
"invalid_sandbox_plan",
|
|
250
|
+
"Sandbox spawn plan must provide options",
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
if (plan.applied && typeof plan.enforcement !== "string") {
|
|
254
|
+
throw this._sandboxError(
|
|
255
|
+
"invalid_sandbox_plan",
|
|
256
|
+
"Applied sandbox spawn plan must name its enforcement",
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
if (!plan.applied && typeof plan.reason !== "string") {
|
|
260
|
+
throw this._sandboxError(
|
|
261
|
+
"invalid_sandbox_plan",
|
|
262
|
+
"Unavailable sandbox spawn plan must provide a reason",
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
const postSpawn = plan.postSpawn || { required: false, mode: "none" };
|
|
266
|
+
if (
|
|
267
|
+
postSpawn.required &&
|
|
268
|
+
postSpawn.mode !== "sync" &&
|
|
269
|
+
postSpawn.mode !== "async"
|
|
270
|
+
) {
|
|
271
|
+
throw this._sandboxError(
|
|
272
|
+
"invalid_sandbox_plan",
|
|
273
|
+
"Required post-spawn enforcement must declare sync or async mode",
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
return {
|
|
277
|
+
...plan,
|
|
278
|
+
args: [...plan.args],
|
|
279
|
+
options: { ...plan.options },
|
|
280
|
+
postSpawn: { ...postSpawn },
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
_prepareSandboxPlan(command, args, options, { sync = false } = {}) {
|
|
285
|
+
const strict = this._sandboxStrictEnabled();
|
|
286
|
+
let disabledReason = null;
|
|
287
|
+
if (this._sandboxDisabledByEnvironment()) {
|
|
288
|
+
disabledReason = "disabled_by_environment";
|
|
289
|
+
} else if (
|
|
290
|
+
this._sandboxEnabled === false ||
|
|
291
|
+
this._platformSandboxEnabled === false
|
|
292
|
+
) {
|
|
293
|
+
disabledReason = "disabled_by_broker";
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (disabledReason) {
|
|
297
|
+
if (strict) {
|
|
298
|
+
throw this._sandboxError(
|
|
299
|
+
disabledReason,
|
|
300
|
+
`Sandbox is unavailable in strict mode: ${disabledReason}`,
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
return this._sandboxUnavailablePlan(
|
|
304
|
+
command,
|
|
305
|
+
args,
|
|
306
|
+
options,
|
|
307
|
+
disabledReason,
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const plan = this._validateSandboxPlan(
|
|
312
|
+
this._sandboxAdapter.applySandbox(
|
|
313
|
+
command,
|
|
314
|
+
args || [],
|
|
315
|
+
options,
|
|
316
|
+
"default",
|
|
317
|
+
),
|
|
318
|
+
);
|
|
319
|
+
|
|
320
|
+
if (!plan.applied && strict) {
|
|
321
|
+
throw this._sandboxError(
|
|
322
|
+
plan.reason || "sandbox_unavailable",
|
|
323
|
+
`Sandbox is unavailable in strict mode: ${
|
|
324
|
+
plan.reason || "unknown reason"
|
|
325
|
+
}`,
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (plan.applied && plan.postSpawn.required) {
|
|
330
|
+
if (typeof this._sandboxAdapter.postSpawnSandbox !== "function") {
|
|
331
|
+
throw this._sandboxError(
|
|
332
|
+
"post_spawn_adapter_unavailable",
|
|
333
|
+
"Required post-spawn sandbox adapter is unavailable",
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
if (sync) {
|
|
337
|
+
throw this._sandboxError(
|
|
338
|
+
"post_spawn_unavailable_for_sync",
|
|
339
|
+
"spawnSync cannot satisfy required post-spawn sandbox enforcement",
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
if (strict && plan.postSpawn.mode !== "sync") {
|
|
343
|
+
throw this._sandboxError(
|
|
344
|
+
"async_post_spawn_disallowed_in_strict_mode",
|
|
345
|
+
"Strict sandbox mode requires synchronous post-spawn enforcement",
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
return plan;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
_applySandboxAudit(auditEntry, plan, applied) {
|
|
353
|
+
auditEntry.sandboxed = applied;
|
|
354
|
+
auditEntry.sandboxProfile = plan?.profile || null;
|
|
355
|
+
auditEntry.sandboxEnforcement = applied
|
|
356
|
+
? plan?.enforcement || "platform"
|
|
357
|
+
: null;
|
|
358
|
+
auditEntry.sandboxReason = applied ? null : plan?.reason || null;
|
|
359
|
+
auditEntry.sandboxState = applied ? "ready" : "unavailable";
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
_recordSandboxDenial(auditEntry, error, startTime) {
|
|
363
|
+
auditEntry.permissionDecision = "deny";
|
|
364
|
+
auditEntry.sandboxed = false;
|
|
365
|
+
auditEntry.sandboxState = "denied";
|
|
366
|
+
auditEntry.sandboxReason =
|
|
367
|
+
error.sandboxReason || "sandbox_initialization_failed";
|
|
368
|
+
auditEntry.deniedReason = `sandbox-init-failed: ${error.message}`;
|
|
369
|
+
auditEntry.endTime = Date.now();
|
|
370
|
+
auditEntry.durationMs = auditEntry.endTime - startTime;
|
|
371
|
+
this._recordAudit(auditEntry);
|
|
372
|
+
this._writeRplEntry(auditEntry, "denied", error);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
_scheduleSandboxCleanup(proc, cleanup) {
|
|
376
|
+
if (typeof cleanup !== "function") return () => {};
|
|
377
|
+
let cleaned = false;
|
|
378
|
+
const run = () => {
|
|
379
|
+
if (cleaned) return;
|
|
380
|
+
cleaned = true;
|
|
381
|
+
cleanup();
|
|
382
|
+
};
|
|
383
|
+
if (proc && typeof proc.once === "function") {
|
|
384
|
+
proc.once("error", run);
|
|
385
|
+
proc.once("exit", run);
|
|
386
|
+
}
|
|
387
|
+
return run;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
_runPostSpawnSandbox(proc, plan, auditEntry) {
|
|
391
|
+
if (!plan.applied || !plan.postSpawn.required) {
|
|
392
|
+
this._applySandboxAudit(auditEntry, plan, plan.applied);
|
|
393
|
+
if (plan.applied) this._stats.sandboxed++;
|
|
394
|
+
const ready = Promise.resolve({ applied: plan.applied });
|
|
395
|
+
proc.sandboxReady = ready;
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
let postSpawnResult;
|
|
400
|
+
try {
|
|
401
|
+
postSpawnResult = this._sandboxAdapter.postSpawnSandbox(proc, plan);
|
|
402
|
+
} catch (error) {
|
|
403
|
+
this._applySandboxAudit(auditEntry, plan, false);
|
|
404
|
+
auditEntry.sandboxState = "failed";
|
|
405
|
+
auditEntry.sandboxReason = `post_spawn_failed: ${error.message}`;
|
|
406
|
+
if (this._sandboxStrictEnabled()) {
|
|
407
|
+
if (typeof proc.once === "function") proc.once("error", () => {});
|
|
408
|
+
try {
|
|
409
|
+
proc.kill?.();
|
|
410
|
+
} catch {
|
|
411
|
+
// The sandbox failure remains fatal even if the child already exited.
|
|
412
|
+
}
|
|
413
|
+
throw this._sandboxError(
|
|
414
|
+
"post_spawn_failed",
|
|
415
|
+
`Post-spawn sandbox setup failed: ${error.message}`,
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
process.emitWarning(
|
|
419
|
+
`Post-spawn sandbox setup failed (continuing without): ${error.message}`,
|
|
420
|
+
);
|
|
421
|
+
proc.sandboxReady = Promise.resolve({ applied: false, error });
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
if (postSpawnResult && typeof postSpawnResult.then === "function") {
|
|
426
|
+
if (this._sandboxStrictEnabled()) {
|
|
427
|
+
Promise.resolve(postSpawnResult).catch(() => {});
|
|
428
|
+
if (typeof proc.once === "function") proc.once("error", () => {});
|
|
429
|
+
try {
|
|
430
|
+
proc.kill?.();
|
|
431
|
+
} catch {
|
|
432
|
+
// The sandbox failure remains fatal even if the child already exited.
|
|
433
|
+
}
|
|
434
|
+
throw this._sandboxError(
|
|
435
|
+
"async_post_spawn_contract_violation",
|
|
436
|
+
"Strict sandbox adapter returned an asynchronous post-spawn result",
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
auditEntry.sandboxed = false;
|
|
440
|
+
auditEntry.sandboxState = "pending";
|
|
441
|
+
const ready = Promise.resolve(postSpawnResult).then(
|
|
442
|
+
() => {
|
|
443
|
+
this._applySandboxAudit(auditEntry, plan, true);
|
|
444
|
+
this._stats.sandboxed++;
|
|
445
|
+
return { applied: true };
|
|
446
|
+
},
|
|
447
|
+
(error) => {
|
|
448
|
+
this._applySandboxAudit(auditEntry, plan, false);
|
|
449
|
+
auditEntry.sandboxState = "failed";
|
|
450
|
+
auditEntry.sandboxReason = `post_spawn_failed: ${error.message}`;
|
|
451
|
+
process.emitWarning(
|
|
452
|
+
`Post-spawn sandbox setup failed (continuing without): ${error.message}`,
|
|
453
|
+
);
|
|
454
|
+
throw error;
|
|
455
|
+
},
|
|
456
|
+
);
|
|
457
|
+
// Keep failures observable to callers without creating an unhandled
|
|
458
|
+
// rejection when a legacy caller does not inspect sandboxReady.
|
|
459
|
+
ready.catch(() => {});
|
|
460
|
+
proc.sandboxReady = ready;
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
this._applySandboxAudit(auditEntry, plan, true);
|
|
465
|
+
this._stats.sandboxed++;
|
|
466
|
+
proc.sandboxReady = Promise.resolve({ applied: true });
|
|
467
|
+
}
|
|
468
|
+
|
|
183
469
|
_credentialBoundaryEnabled() {
|
|
184
470
|
return (
|
|
185
471
|
this._credentialFilteringEnabled !== false &&
|
|
@@ -293,7 +579,9 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
293
579
|
},
|
|
294
580
|
auditEntry.origin,
|
|
295
581
|
);
|
|
296
|
-
} catch
|
|
582
|
+
} catch {
|
|
583
|
+
// Provenance reporting must not hide the process execution result.
|
|
584
|
+
}
|
|
297
585
|
}
|
|
298
586
|
|
|
299
587
|
_emitHooksEvent(event, data) {
|
|
@@ -301,7 +589,9 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
301
589
|
if (!hooks || !hooks.hooksV2) return;
|
|
302
590
|
try {
|
|
303
591
|
hooks.hooksV2.emit(event, data);
|
|
304
|
-
} catch {
|
|
592
|
+
} catch {
|
|
593
|
+
// Hook reporting must not hide the process execution result.
|
|
594
|
+
}
|
|
305
595
|
}
|
|
306
596
|
|
|
307
597
|
spawn(command, args, options = {}) {
|
|
@@ -388,59 +678,57 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
388
678
|
}
|
|
389
679
|
|
|
390
680
|
// P0-1: Platform sandbox wrapping — apply macOS/Windows/Linux sandbox
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
optsForSpawn,
|
|
400
|
-
"default",
|
|
401
|
-
);
|
|
402
|
-
if (result && result.applied) {
|
|
403
|
-
Object.assign(optsForSpawn, result.options || {});
|
|
404
|
-
if (result.command) command = result.command;
|
|
405
|
-
if (result.args) args = result.args;
|
|
406
|
-
sandboxApplied = true;
|
|
407
|
-
sandboxProfile = result.profile || null;
|
|
408
|
-
this._stats.sandboxed++;
|
|
409
|
-
}
|
|
410
|
-
auditEntry.sandboxed = sandboxApplied;
|
|
411
|
-
auditEntry.sandboxProfile = sandboxProfile;
|
|
412
|
-
} catch (sandboxErr) {
|
|
413
|
-
// Fail closed: if sandbox setup fails on strict, deny spawn
|
|
414
|
-
if (process.env.CC_SANDBOX_STRICT === "1") {
|
|
415
|
-
auditEntry.deniedReason = `sandbox-init-failed: ${sandboxErr.message}`;
|
|
416
|
-
this._auditLog.push(auditEntry);
|
|
417
|
-
const err = new Error(`Sandbox init failed: ${sandboxErr.message}`);
|
|
418
|
-
err.auditEntry = auditEntry;
|
|
419
|
-
throw err;
|
|
420
|
-
}
|
|
421
|
-
// Non-strict: warn but allow (development mode)
|
|
422
|
-
process.emitWarning(
|
|
423
|
-
`Sandbox init failed (continuing without): ${sandboxErr.message}`,
|
|
424
|
-
);
|
|
681
|
+
let sandboxPlan;
|
|
682
|
+
try {
|
|
683
|
+
sandboxPlan = this._prepareSandboxPlan(command, args || [], spawnOpts);
|
|
684
|
+
} catch (sandboxErr) {
|
|
685
|
+
if (this._sandboxStrictEnabled()) {
|
|
686
|
+
this._recordSandboxDenial(auditEntry, sandboxErr, startTime);
|
|
687
|
+
sandboxErr.auditEntry = auditEntry;
|
|
688
|
+
throw sandboxErr;
|
|
425
689
|
}
|
|
690
|
+
process.emitWarning(
|
|
691
|
+
`Sandbox init failed (continuing without): ${sandboxErr.message}`,
|
|
692
|
+
);
|
|
693
|
+
sandboxPlan = this._sandboxUnavailablePlan(
|
|
694
|
+
command,
|
|
695
|
+
args || [],
|
|
696
|
+
spawnOpts,
|
|
697
|
+
`sandbox_init_failed: ${sandboxErr.message}`,
|
|
698
|
+
);
|
|
426
699
|
}
|
|
700
|
+
command = sandboxPlan.command;
|
|
701
|
+
args = [...sandboxPlan.args];
|
|
702
|
+
const optsForSpawn = { ...sandboxPlan.options };
|
|
703
|
+
this._applySandboxAudit(
|
|
704
|
+
auditEntry,
|
|
705
|
+
sandboxPlan,
|
|
706
|
+
sandboxPlan.applied && !sandboxPlan.postSpawn.required,
|
|
707
|
+
);
|
|
427
708
|
|
|
428
709
|
// Use native spawn from _native (set by patch-child-process.js)
|
|
429
710
|
const nativeSpawnFn = this._native?.spawn || nativeSpawn;
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
} catch (postErr) {
|
|
437
|
-
process.emitWarning(
|
|
438
|
-
`Post-spawn sandbox setup failed: ${postErr.message}`,
|
|
439
|
-
);
|
|
440
|
-
}
|
|
711
|
+
let proc;
|
|
712
|
+
try {
|
|
713
|
+
proc = nativeSpawnFn(command, args, optsForSpawn);
|
|
714
|
+
} catch (spawnError) {
|
|
715
|
+
sandboxPlan.cleanup?.();
|
|
716
|
+
throw spawnError;
|
|
441
717
|
}
|
|
442
|
-
|
|
443
718
|
auditEntry.pid = proc.pid;
|
|
719
|
+
const cleanupSandbox = this._scheduleSandboxCleanup(
|
|
720
|
+
proc,
|
|
721
|
+
sandboxPlan.cleanup,
|
|
722
|
+
);
|
|
723
|
+
try {
|
|
724
|
+
this._runPostSpawnSandbox(proc, sandboxPlan, auditEntry);
|
|
725
|
+
} catch (postSpawnError) {
|
|
726
|
+
cleanupSandbox();
|
|
727
|
+
this._recordSandboxDenial(auditEntry, postSpawnError, startTime);
|
|
728
|
+
postSpawnError.auditEntry = auditEntry;
|
|
729
|
+
throw postSpawnError;
|
|
730
|
+
}
|
|
731
|
+
|
|
444
732
|
this._recordAudit(auditEntry);
|
|
445
733
|
this._writeRplEntry(auditEntry, "started");
|
|
446
734
|
this._emitHooksEvent("tool:start", {
|
|
@@ -563,44 +851,36 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
563
851
|
}
|
|
564
852
|
|
|
565
853
|
// P0-1: Platform sandbox wrapping (sync path)
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
);
|
|
577
|
-
if (result && result.applied) {
|
|
578
|
-
Object.assign(optsForSync, result.options || {});
|
|
579
|
-
if (result.command) command = result.command;
|
|
580
|
-
if (result.args) args = result.args;
|
|
581
|
-
sandboxApplied = true;
|
|
582
|
-
sandboxProfile = result.profile || null;
|
|
583
|
-
this._stats.sandboxed++;
|
|
584
|
-
}
|
|
585
|
-
auditEntry.sandboxed = sandboxApplied;
|
|
586
|
-
auditEntry.sandboxProfile = sandboxProfile;
|
|
587
|
-
} catch (sandboxErr) {
|
|
588
|
-
if (process.env.CC_SANDBOX_STRICT === "1") {
|
|
589
|
-
auditEntry.deniedReason = `sandbox-init-failed: ${sandboxErr.message}`;
|
|
590
|
-
this._recordAudit(auditEntry);
|
|
591
|
-
const err = new Error(`Sandbox init failed: ${sandboxErr.message}`);
|
|
592
|
-
err.auditEntry = auditEntry;
|
|
593
|
-
throw err;
|
|
594
|
-
}
|
|
595
|
-
process.emitWarning(
|
|
596
|
-
`Sandbox init failed (sync): ${sandboxErr.message}`,
|
|
597
|
-
);
|
|
854
|
+
let sandboxPlan;
|
|
855
|
+
try {
|
|
856
|
+
sandboxPlan = this._prepareSandboxPlan(command, args || [], spawnOpts, {
|
|
857
|
+
sync: true,
|
|
858
|
+
});
|
|
859
|
+
} catch (sandboxErr) {
|
|
860
|
+
if (this._sandboxStrictEnabled()) {
|
|
861
|
+
this._recordSandboxDenial(auditEntry, sandboxErr, startTime);
|
|
862
|
+
sandboxErr.auditEntry = auditEntry;
|
|
863
|
+
throw sandboxErr;
|
|
598
864
|
}
|
|
865
|
+
process.emitWarning(
|
|
866
|
+
`Sandbox init failed (sync, continuing without): ${sandboxErr.message}`,
|
|
867
|
+
);
|
|
868
|
+
sandboxPlan = this._sandboxUnavailablePlan(
|
|
869
|
+
command,
|
|
870
|
+
args || [],
|
|
871
|
+
spawnOpts,
|
|
872
|
+
`sandbox_init_failed: ${sandboxErr.message}`,
|
|
873
|
+
);
|
|
599
874
|
}
|
|
875
|
+
command = sandboxPlan.command;
|
|
876
|
+
args = [...sandboxPlan.args];
|
|
877
|
+
const optsForSync = { ...sandboxPlan.options };
|
|
878
|
+
this._applySandboxAudit(auditEntry, sandboxPlan, sandboxPlan.applied);
|
|
600
879
|
|
|
601
880
|
const nativeSpawnSyncFn = this._native?.spawnSync || nativeSpawnSync;
|
|
602
881
|
try {
|
|
603
882
|
const result = nativeSpawnSyncFn(command, args, optsForSync);
|
|
883
|
+
if (sandboxPlan.applied) this._stats.sandboxed++;
|
|
604
884
|
auditEntry.exitCode = result.status;
|
|
605
885
|
auditEntry.endTime = Date.now();
|
|
606
886
|
auditEntry.durationMs = auditEntry.endTime - startTime;
|
|
@@ -614,6 +894,8 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
614
894
|
this._recordAudit(auditEntry);
|
|
615
895
|
this._writeRplEntry(auditEntry, "error", err);
|
|
616
896
|
throw err;
|
|
897
|
+
} finally {
|
|
898
|
+
sandboxPlan.cleanup?.();
|
|
617
899
|
}
|
|
618
900
|
}
|
|
619
901
|
|
|
@@ -803,7 +1085,9 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
803
1085
|
completionError.stream = streamName;
|
|
804
1086
|
try {
|
|
805
1087
|
proc.kill(options.killSignal || "SIGTERM");
|
|
806
|
-
} catch {
|
|
1088
|
+
} catch {
|
|
1089
|
+
// The maxBuffer error remains authoritative if the child exited.
|
|
1090
|
+
}
|
|
807
1091
|
}
|
|
808
1092
|
});
|
|
809
1093
|
};
|