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