chainlesschain 0.162.183 → 0.162.185
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 +1 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-BapS7lz4.js → AIOps-Co4ipAKx.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CXYdXEUI.js → ActionButton-BpsoDrDq.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-CKR5Lexn.js → Analytics-DMUqeBik.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DATVUOXB.js → AppLayout-C6fD_dXr.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-vb_0ZlV1.js → Artifacts-DW0YlQlV.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-BI1l9GWt.js → Audit-DXtHiiFK.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-BFXbaUEf.js → BackgroundAgents-BgmF62U-.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DEYBJJ6H.js → Backup-D8vhVLQC.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-COdzeO0M.js → BaseInput-D7nCtY2X.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-oSN6sfM5.js → Chat-CBZLEV2G.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-CI_jT0ru.js → ChatBubbleRenderer-CtDb-2Qu.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-BezEa4tm.js → Checkbox-DJLkeD4M.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-CNEL0Ife.js → Codegen-Cs6xO8Fd.js} +1 -1
- package/src/assets/web-panel/assets/{Col-Bf2Y2Bn1.js → Col-Dtx9wxfT.js} +1 -1
- package/src/assets/web-panel/assets/{Community-BfUlu4Hc.js → Community-DiigJg4n.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BN4xWP9e.js → Compact-B67oMDDL.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-Bt6BKmEP.js → Compliance-BBDl-Jos.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-DKLp8YxO.js → Cowork-Ba98hSsa.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-o7Hhw6ky.js → Cron-DBWQZIz7.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-DaNXWJIw.js → Crosschain-OcrKzxAt.js} +1 -1
- package/src/assets/web-panel/assets/{DID-B-Qa2mha.js → DID-mW2eSbjM.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-CMX0Qnxw.js → Dashboard-BmsDPmKJ.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BLuLyRu_.js → Dropdown-CVzmCyRx.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CFBAeMij.js → EmailListRenderer-vVgqKzhh.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-DWzXQ67V.js → FamilyGuardDashboard-CWY5t_ZJ.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DB1QSLgr.js → Federation-ZGomhjxr.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-C-OKCToP.js → FormItemContext-DyaknbLr.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-DMJFtFZf.js → GenericCardRenderer-CmIvN1qr.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DsGSujOV.js → Git-DQOJIYkG.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-B0iS9NEW.js → Governance-CMiY-EEp.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CH004H7c.js → Inference-D6IXuucf.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-Q9MTQ83c.js → KnowledgeGraph-6jkTL0hV.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-B_fyjZK9.js → Logs-N0jD-349.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-BL1IVXm-.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-BIStF9d1.js → Marketplace-WhYuhBxm.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-pGfal768.js → McpTools-DTeO28xy.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-xbNqpIqB.js → Memory-MSHzPSE-.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-B5EQGrIK.js → MobileBridge-Cyqs3J3W.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-7IN2hWHg.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-a_rmfxJH.js → Mtc-MWBnezNM.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-BmKuofUr.js → MtcAudit-DQu35Nu-.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-BQbJ-CAN.js → Multisig-CQS_M-DP.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-JtPJKX25.js → NLProgramming-WD16vQvY.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-ZFKznTSG.js → Notes-DqsiSwOq.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-B6aHRBBR.js → NotificationSettings-D3LoxO-P.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-DdcsOqEz.js → OrderTableRenderer-C5jPoTd6.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BFDTAUgS.js → Organization-48aMBJso.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-0FoTfbWH.js → Overflow-j-a2XkhR.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CWd90etw.js → P2P-BYpBNYnh.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-DtCGC-W-.js → PdhVaultBrowser-CYCsrrLg.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-CvQ7nr7T.js → Permissions-ZRXGXDFb.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-rdNPcR-Z.js → PersonalDataHub-6OWUPHyL.js} +5 -5
- package/src/assets/web-panel/assets/{Pipeline-CmrfiNOs.js → Pipeline-FcjlDK9E.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-D7ep1h_t.js → Privacy-vD_6Tldp.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-C0xKINHS.js → ProjectInit-B_CHOLXp.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-AOmZFp-F.js → ProjectSettings-rEiqQ2da.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-BWHSkXZP.js → Projects-Bg8obRAM.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-Cb7JCTPL.js → Providers-Dgtt97B4.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-BDMehcXC.js → QrScannerModal-DaGVylZO.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-BF6_1nvx.js → QuickAsk-DP2_2x3u.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-BHfT-A28.js → Recommend-D29yj4ki.js} +1 -1
- package/src/assets/web-panel/assets/RemoteSession-Ue2wnBLp.js +5 -0
- package/src/assets/web-panel/assets/{Reputation-CsWHLEcj.js → Reputation-CrxIHqeC.js} +1 -1
- package/src/assets/web-panel/assets/{Row-D6srnWhm.js → Row-BgSzJPCn.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-Xhr-KyVd.js → RssFeed-AwhYOrP9.js} +3 -3
- package/src/assets/web-panel/assets/{Search-vIbIJvwL.js → Search-D2shpEcm.js} +1 -1
- package/src/assets/web-panel/assets/{Security-Bzi5Aiko.js → Security-BtKzhTbT.js} +4 -4
- package/src/assets/web-panel/assets/{Services-BHtVX52P.js → Services-BY0DsUSm.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-C0R8B2jf.js → Skeleton-B3Sb0UI9.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-DtT6rWOX.js → Skills-Ne5w0bDs.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-0B37mxVU.js → Sla-C8VkaP4T.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-0V2jE1Bs.js → SpeechSettings-BQdIEYP9.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-CYedRzaj.js → SyncSettings-CwFafrUg.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-yJuKoDlR.js +1 -0
- package/src/assets/web-panel/assets/{Templates-BKoHztGT.js → Templates-DYn9qCmx.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant--17nwVNZ.js → Tenant-DkKReHvn.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-r6bd-owt.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-C5jx4AE3.js → TimelineRenderer-Mq2juUC3.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-DYJKYa9t.js → Tokens-BnMw7MRi.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DChpWiQ9.js → Trigger-CTzKp4o9.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DfWG52EA.js → Trust-BBrSZm9U.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-CMugYcyA.js → UkeySign-D9fDvEMq.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BOSmrHAd.js → VideoEditing-DUi5ve-0.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-D5g3k3Sa.js → Wallet-C8Fi1P8_.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-D-7u4Mkc.js → WebAuthn-s1LppYi2.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-CFzZMSUJ.js → WorkflowEditor-DJL2C4lj.js} +1 -1
- package/src/assets/web-panel/assets/{chat-VbR6l6mc.js → chat-D3F2ndOB.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BSZn8EDS.js → colors-B7739-e3.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-y74obMEq.js → compact-item-CcJbFTF4.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-C326bjex.js → createContext-CuP_DEFS.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-Cj_36GHq.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-D_INJQT_.js → hasIn-6YEXfIik.js} +1 -1
- package/src/assets/web-panel/assets/{index-DuIkfnTF.js → index-4h3lpWJ3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DBkzrpiL.js → index-BIID4XcP.js} +1 -1
- package/src/assets/web-panel/assets/{index-B7SrC-On.js → index-BOHUo3aM.js} +1 -1
- package/src/assets/web-panel/assets/{index-BnSfnSMP.js → index-BYYSLEjn.js} +1 -1
- package/src/assets/web-panel/assets/{index-KF9Zmqln.js → index-Bh4hcNWW.js} +1 -1
- package/src/assets/web-panel/assets/{index-C327pLbw.js → index-BhIKnQAW.js} +1 -1
- package/src/assets/web-panel/assets/{index-E_v1ZCTP.js → index-Bru_kpZl.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bfw2hf2s.js → index-BsdSnHQE.js} +1 -1
- package/src/assets/web-panel/assets/{index-jYaogFE8.js → index-BxSqVMGh.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dlxh9D8D.js → index-C3ZA_h1j.js} +1 -1
- package/src/assets/web-panel/assets/{index-DdyjrCAu.js → index-C3pctdCb.js} +1 -1
- package/src/assets/web-panel/assets/{index-abmn_8Yz.js → index-CRuoRapN.js} +1 -1
- package/src/assets/web-panel/assets/{index-qMA4GYdQ.js → index-CY0zd_jc.js} +1 -1
- package/src/assets/web-panel/assets/index-CezFrAmD.js +1 -0
- package/src/assets/web-panel/assets/index-Cxgguez6.js +1 -0
- package/src/assets/web-panel/assets/{index-Cr3uuz0C.js → index-CxradkS6.js} +19 -19
- package/src/assets/web-panel/assets/{index-DwHSZLXg.js → index-D0K_rFC1.js} +1 -1
- package/src/assets/web-panel/assets/{index-CMHqs3Jb.js → index-D0zdPyTD.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bnua8IX3.js → index-D3haorUt.js} +1 -1
- package/src/assets/web-panel/assets/{index-BY8-nCgs.js → index-D6Ij_2uw.js} +1 -1
- package/src/assets/web-panel/assets/{index-FQBsuExX.js → index-DDRlBaDt.js} +1 -1
- package/src/assets/web-panel/assets/{index-C-ZCaUJc.js → index-DGsE7MQz.js} +1 -1
- package/src/assets/web-panel/assets/{index-BjcWKg1S.js → index-DHvxXXNA.js} +1 -1
- package/src/assets/web-panel/assets/{index-GA80ir_u.js → index-DV11jpeO.js} +1 -1
- package/src/assets/web-panel/assets/{index-CsovTpx9.js → index-DXdnfDVK.js} +1 -1
- package/src/assets/web-panel/assets/{index-nSn2-C4N.js → index-D_75jYWk.js} +1 -1
- package/src/assets/web-panel/assets/{index-BJi3UqBt.js → index-DjI9MkId.js} +1 -1
- package/src/assets/web-panel/assets/{index-gINyI1rh.js → index-DlSvpNMf.js} +1 -1
- package/src/assets/web-panel/assets/{index-CfLJ42kv.js → index-Dox44j29.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2NyllnW.js → index-DpEKmjoa.js} +1 -1
- package/src/assets/web-panel/assets/{index-Iw0FfqUz.js → index-Dsy7_x4s.js} +1 -1
- package/src/assets/web-panel/assets/{index-4eyH-eC2.js → index-Gxw09e9R.js} +1 -1
- package/src/assets/web-panel/assets/{index-4PIeTM--.js → index-LfRlSmqe.js} +1 -1
- package/src/assets/web-panel/assets/{index-IZAWt0H8.js → index-Nz-MUHD1.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUU2606o.js → index-b9cuvFEv.js} +1 -1
- package/src/assets/web-panel/assets/{index-CzE53HiB.js → index-eR6H6NR7.js} +1 -1
- package/src/assets/web-panel/assets/{index-9PIVuXqo.js → index-fWgUQZ9d.js} +1 -1
- package/src/assets/web-panel/assets/{index-DkH1JvEt.js → index-mfWQRSLn.js} +1 -1
- package/src/assets/web-panel/assets/{index-DNMxIsDg.js → index-yOZYSNmG.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-DI0Zaf8-.js → initDefaultProps-CJ1Bq2L3.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BZDKSy3Z.js → motion-rYJN_vzf.js} +1 -1
- package/src/assets/web-panel/assets/{move-DsIW01Vp.js → move-DnDK2gTP.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-CohkDhsf.js → mtc-parser-CKnXy7ES.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DpiN5rzg.js → omit-3nRc3hWT.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-qbuqni3y.js → pickAttrs-Ddjj3sLu.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-mBky6714.js → placementArrow-CbsbphQY.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-Bas3eQ2K.js → responsiveObserve-D9aZ4VDJ.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CBx_SKoK.js → slide-D4pvdFj0.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-BlYguJSV.js → statusUtils-C2W-vY-S.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BCYQmRGv.js → styleChecker-Cbq5150d.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-Dp5dybLM.js → useFlexGapSupport-BA2B7R82.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DHAMBgA2.js → useFs-CLrwg3xg.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-W6jsSw76.js → usePersonalDataHub-DQeAI5qs.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-BkI6aayc.js → vnode-8BDGy-YU.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-C_IMGueq.js → zoom-B2SzFprl.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agenda.js +74 -1
- package/src/commands/background-session.js +11 -1
- package/src/commands/batch.js +160 -5
- package/src/commands/plugin.js +90 -27
- package/src/commands/session.js +31 -1
- package/src/commands/team.js +212 -6
- package/src/data/changelog.json +26 -0
- package/src/gateways/terminal/PtyManager.js +45 -15
- package/src/gateways/ws/ws-agent-handler.js +15 -1
- package/src/gateways/ws/ws-session-gateway.js +88 -0
- package/src/harness/background-task-command-runner.js +234 -0
- package/src/harness/background-task-manager.js +150 -20
- package/src/harness/background-task-worker.js +17 -11
- package/src/harness/jsonl-session-store.js +57 -6
- package/src/harness/mcp-client.js +65 -43
- package/src/lib/agent-batch.js +4 -1
- package/src/lib/agent-team/team-worktree.js +3 -0
- package/src/lib/async-hook-supervisor.cjs +82 -10
- package/src/lib/async-hook-supervisor.js +50 -4
- package/src/lib/background-agent-supervisor.js +46 -0
- package/src/lib/collaboration-run-store.js +362 -0
- package/src/lib/event-runtime-host.js +12 -10
- package/src/lib/hook-runner.cjs +105 -18
- package/src/lib/hook-runner.js +79 -6
- package/src/lib/hook-shell-command.cjs +148 -0
- package/src/lib/hooks-v2-runtime.js +280 -81
- package/src/lib/hooks-v2-workspace-context.js +258 -0
- package/src/lib/jsonl-session-store.js +2 -0
- package/src/lib/lsp/__tests__/lsp-client.test.js +15 -0
- package/src/lib/lsp/lsp-client.js +12 -1
- package/src/lib/plugin-monitor-supervisor.js +53 -16
- package/src/lib/plugin-runtime/bin.js +21 -5
- package/src/lib/plugin-runtime/install.js +249 -57
- package/src/lib/plugin-runtime/mcp.js +21 -2
- package/src/lib/plugin-runtime/monitors.js +19 -3
- package/src/lib/plugin-runtime/sandbox-policy.js +100 -4
- package/src/lib/process-execution-broker/index.js +1151 -44
- package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +1557 -0
- package/src/lib/process-execution-broker/linux-generic-bwrap.js +1378 -0
- package/src/lib/process-execution-broker/platform-sandbox.js +586 -58
- package/src/lib/session-usage.js +202 -2
- package/src/lib/stream-retry.js +29 -0
- package/src/repl/agent-repl.js +40 -3
- package/src/runtime/agent-core.js +304 -42
- package/src/runtime/headless-runner.js +48 -1
- package/src/runtime/headless-stream.js +42 -2
- package/src/workers/background-agent-worker.js +5 -11
- package/src/assets/web-panel/assets/MarkdownRenderer-C0o4FtpD.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-VTc3gT1y.js +0 -1
- package/src/assets/web-panel/assets/RemoteSession-B6EEf8hh.js +0 -5
- package/src/assets/web-panel/assets/Tasks-D-R1x8vm.js +0 -1
- package/src/assets/web-panel/assets/Terminal-Dnkos7vW.js +0 -3
- package/src/assets/web-panel/assets/devWarning-D3Bho_6u.js +0 -1
- package/src/assets/web-panel/assets/index-5iAFwYx1.js +0 -1
- package/src/assets/web-panel/assets/index-BfnB7LPx.js +0 -1
package/src/lib/hook-runner.cjs
CHANGED
|
@@ -26,9 +26,14 @@ const {
|
|
|
26
26
|
loadShellConfig,
|
|
27
27
|
} = require("./shell-selector.cjs");
|
|
28
28
|
const { mergeHookDecisions } = require("./hook-event-bus.cjs");
|
|
29
|
+
const { buildManagedHookEnvironment } = require("./hook-environment.cjs");
|
|
29
30
|
const {
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
buildExplicitHookShellInvocation,
|
|
32
|
+
issueTrustedHookSandboxContract,
|
|
33
|
+
requireTrustedHookRoot,
|
|
34
|
+
requiresExplicitHookShell,
|
|
35
|
+
sandboxBoundaryError,
|
|
36
|
+
} = require("./hook-shell-command.cjs");
|
|
32
37
|
|
|
33
38
|
const _deps = { runSync: null, run: null };
|
|
34
39
|
Object.defineProperties(_deps, {
|
|
@@ -125,17 +130,13 @@ function hookSpawnFailure(error) {
|
|
|
125
130
|
const sandboxDenied =
|
|
126
131
|
error?.code === "ERR_PROCESS_SANDBOX_BOUNDARY_UNSATISFIED";
|
|
127
132
|
return {
|
|
128
|
-
decision: sandboxDenied
|
|
129
|
-
? HOOK_DECISIONS.BLOCK
|
|
130
|
-
: HOOK_DECISIONS.CONTINUE,
|
|
133
|
+
decision: sandboxDenied ? HOOK_DECISIONS.BLOCK : HOOK_DECISIONS.CONTINUE,
|
|
131
134
|
reason: sandboxDenied
|
|
132
135
|
? `hook sandbox denied: ${error.message}`
|
|
133
136
|
: `hook spawn failed: ${error.message}`,
|
|
134
137
|
exitCode: null,
|
|
135
138
|
error: error.message,
|
|
136
|
-
...(sandboxDenied
|
|
137
|
-
? { sandboxDenied: true }
|
|
138
|
-
: { nonBlockingError: true }),
|
|
139
|
+
...(sandboxDenied ? { sandboxDenied: true } : { nonBlockingError: true }),
|
|
139
140
|
};
|
|
140
141
|
}
|
|
141
142
|
|
|
@@ -321,12 +322,17 @@ function _runCommandHookInner(command, input = {}, opts = {}) {
|
|
|
321
322
|
let res;
|
|
322
323
|
try {
|
|
323
324
|
const sandboxPolicy = resolveHookSandboxPolicy({}, opts);
|
|
325
|
+
const explicitSandboxShell = requiresExplicitHookShell(sandboxPolicy);
|
|
326
|
+
const trustedRoot = explicitSandboxShell
|
|
327
|
+
? requireTrustedHookRoot(cwd)
|
|
328
|
+
: null;
|
|
329
|
+
const workingDirectory = trustedRoot || cwd || process.cwd();
|
|
324
330
|
const common = {
|
|
325
331
|
input: JSON.stringify({
|
|
326
332
|
...input,
|
|
327
333
|
schema_version: input.schema_version ?? HOOK_PAYLOAD_SCHEMA_VERSION,
|
|
328
334
|
}),
|
|
329
|
-
cwd:
|
|
335
|
+
cwd: workingDirectory,
|
|
330
336
|
encoding: "utf-8",
|
|
331
337
|
timeout,
|
|
332
338
|
maxBuffer: 8 * 1024 * 1024,
|
|
@@ -346,6 +352,7 @@ function _runCommandHookInner(command, input = {}, opts = {}) {
|
|
|
346
352
|
pluginId: opts.pluginId || null,
|
|
347
353
|
pluginVersion: opts.pluginVersion || null,
|
|
348
354
|
pluginSource: opts.pluginSource || null,
|
|
355
|
+
...(explicitSandboxShell || usePowershell ? { shell: false } : {}),
|
|
349
356
|
...(sandboxPolicy ? { sandboxPolicy } : {}),
|
|
350
357
|
};
|
|
351
358
|
const brokerRunSync =
|
|
@@ -355,13 +362,42 @@ function _runCommandHookInner(command, input = {}, opts = {}) {
|
|
|
355
362
|
? opts.broker["spawnSync"].bind(opts.broker)
|
|
356
363
|
: null;
|
|
357
364
|
if (brokerRunSync) {
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
365
|
+
const powershellOptions = {
|
|
366
|
+
executionPolicy: loadShellConfig({ cwd: common.cwd }).executionPolicy,
|
|
367
|
+
};
|
|
368
|
+
const invocation = explicitSandboxShell
|
|
369
|
+
? buildExplicitHookShellInvocation(command, {
|
|
370
|
+
shellKind,
|
|
371
|
+
buildPowershellArgv,
|
|
372
|
+
powershellOptions,
|
|
362
373
|
})
|
|
363
|
-
:
|
|
364
|
-
|
|
374
|
+
: usePowershell
|
|
375
|
+
? buildPowershellArgv(command, shellKind, powershellOptions)
|
|
376
|
+
: { file: command, argv: [] };
|
|
377
|
+
let brokerOptions = processOptions;
|
|
378
|
+
if (explicitSandboxShell) {
|
|
379
|
+
const issuer = opts.broker?.issueLinuxWorkspaceSandboxExecutionContract;
|
|
380
|
+
const sandboxExecutionContract = issueTrustedHookSandboxContract({
|
|
381
|
+
issuer,
|
|
382
|
+
receiver: opts.broker,
|
|
383
|
+
file: invocation.file,
|
|
384
|
+
args: invocation.argv,
|
|
385
|
+
options: processOptions,
|
|
386
|
+
trustedRoot,
|
|
387
|
+
sync: true,
|
|
388
|
+
label: "trusted plugin hook sandbox contract issuance failed",
|
|
389
|
+
});
|
|
390
|
+
if (process.platform === "linux" && !sandboxExecutionContract) {
|
|
391
|
+
throw sandboxBoundaryError(
|
|
392
|
+
"trusted Linux hook sandbox contract issuer is unavailable",
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
brokerOptions = {
|
|
396
|
+
...processOptions,
|
|
397
|
+
...(sandboxExecutionContract ? { sandboxExecutionContract } : {}),
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
res = brokerRunSync(invocation.file, invocation.argv, brokerOptions);
|
|
365
401
|
} else if (usePowershell) {
|
|
366
402
|
// Per-hook `shell: powershell|pwsh` (settings hook entry): explicit argv
|
|
367
403
|
// instead of the default shell; the enterprise ExecutionPolicy override
|
|
@@ -374,6 +410,12 @@ function _runCommandHookInner(command, input = {}, opts = {}) {
|
|
|
374
410
|
throw new Error("hook process runner unavailable");
|
|
375
411
|
}
|
|
376
412
|
res = _deps.runSync(inv.file, inv.argv, processOptions);
|
|
413
|
+
} else if (explicitSandboxShell) {
|
|
414
|
+
if (typeof _deps.runSync !== "function") {
|
|
415
|
+
throw new Error("hook process runner unavailable");
|
|
416
|
+
}
|
|
417
|
+
const invocation = buildExplicitHookShellInvocation(command);
|
|
418
|
+
res = _deps.runSync(invocation.file, invocation.argv, processOptions);
|
|
377
419
|
} else {
|
|
378
420
|
if (typeof _deps.runSync !== "function") {
|
|
379
421
|
throw new Error("hook process runner unavailable");
|
|
@@ -396,7 +438,13 @@ function _runCommandHookInner(command, input = {}, opts = {}) {
|
|
|
396
438
|
function interpretHookOutcome(res) {
|
|
397
439
|
// A surfaced spawn error (timeout / ENOENT, status null) is non-blocking — a
|
|
398
440
|
// broken hook must never wedge the agent; only an explicit block blocks.
|
|
399
|
-
|
|
441
|
+
// spawnSync can also report EPIPE after a fast-exiting hook closes stdin,
|
|
442
|
+
// even though the child has a real exit status and complete output. The
|
|
443
|
+
// async runner already treats that early stdin close as harmless; preserve
|
|
444
|
+
// the exit-code/stdout protocol on the sync path as well.
|
|
445
|
+
const inputClosedAfterExit =
|
|
446
|
+
res.error?.code === "EPIPE" && Number.isInteger(res.status);
|
|
447
|
+
if (res.error && !inputClosedAfterExit) {
|
|
400
448
|
return {
|
|
401
449
|
decision: HOOK_DECISIONS.CONTINUE,
|
|
402
450
|
reason: `hook error: ${res.error.message}`,
|
|
@@ -467,7 +515,6 @@ async function _runCommandHookInnerAsync(command, input = {}, opts = {}) {
|
|
|
467
515
|
: 60000;
|
|
468
516
|
const shellKind = normalizeShellKind(opts.shell);
|
|
469
517
|
const usePowershell = shellKind === "powershell" || shellKind === "pwsh";
|
|
470
|
-
const wd = cwd || process.cwd();
|
|
471
518
|
const inputJson = JSON.stringify({
|
|
472
519
|
...input,
|
|
473
520
|
schema_version: input.schema_version ?? HOOK_PAYLOAD_SCHEMA_VERSION,
|
|
@@ -485,6 +532,14 @@ async function _runCommandHookInnerAsync(command, input = {}, opts = {}) {
|
|
|
485
532
|
} catch (error) {
|
|
486
533
|
return hookSpawnFailure(error);
|
|
487
534
|
}
|
|
535
|
+
const explicitSandboxShell = requiresExplicitHookShell(sandboxPolicy);
|
|
536
|
+
let trustedRoot;
|
|
537
|
+
try {
|
|
538
|
+
trustedRoot = explicitSandboxShell ? requireTrustedHookRoot(cwd) : null;
|
|
539
|
+
} catch (error) {
|
|
540
|
+
return hookSpawnFailure(error);
|
|
541
|
+
}
|
|
542
|
+
const wd = trustedRoot || cwd || process.cwd();
|
|
488
543
|
const processOptions = {
|
|
489
544
|
cwd: wd,
|
|
490
545
|
env: spawnEnv,
|
|
@@ -494,6 +549,7 @@ async function _runCommandHookInnerAsync(command, input = {}, opts = {}) {
|
|
|
494
549
|
pluginId: opts.pluginId || null,
|
|
495
550
|
pluginVersion: opts.pluginVersion || null,
|
|
496
551
|
pluginSource: opts.pluginSource || null,
|
|
552
|
+
...(explicitSandboxShell || usePowershell ? { shell: false } : {}),
|
|
497
553
|
...(sandboxPolicy ? { sandboxPolicy } : {}),
|
|
498
554
|
};
|
|
499
555
|
|
|
@@ -509,7 +565,38 @@ async function _runCommandHookInnerAsync(command, input = {}, opts = {}) {
|
|
|
509
565
|
if (typeof run !== "function") {
|
|
510
566
|
throw new Error("hook process runner unavailable");
|
|
511
567
|
}
|
|
512
|
-
if (
|
|
568
|
+
if (explicitSandboxShell) {
|
|
569
|
+
const invocation = buildExplicitHookShellInvocation(command, {
|
|
570
|
+
shellKind,
|
|
571
|
+
buildPowershellArgv,
|
|
572
|
+
powershellOptions: {
|
|
573
|
+
executionPolicy: loadShellConfig({ cwd: wd }).executionPolicy,
|
|
574
|
+
},
|
|
575
|
+
});
|
|
576
|
+
let brokerOptions = processOptions;
|
|
577
|
+
if (brokerRun) {
|
|
578
|
+
const issuer = opts.broker?.issueLinuxWorkspaceSandboxExecutionContract;
|
|
579
|
+
const sandboxExecutionContract = issueTrustedHookSandboxContract({
|
|
580
|
+
issuer,
|
|
581
|
+
receiver: opts.broker,
|
|
582
|
+
file: invocation.file,
|
|
583
|
+
args: invocation.argv,
|
|
584
|
+
options: processOptions,
|
|
585
|
+
trustedRoot,
|
|
586
|
+
label: "trusted plugin hook sandbox contract issuance failed",
|
|
587
|
+
});
|
|
588
|
+
if (process.platform === "linux" && !sandboxExecutionContract) {
|
|
589
|
+
throw sandboxBoundaryError(
|
|
590
|
+
"trusted Linux hook sandbox contract issuer is unavailable",
|
|
591
|
+
);
|
|
592
|
+
}
|
|
593
|
+
brokerOptions = {
|
|
594
|
+
...processOptions,
|
|
595
|
+
...(sandboxExecutionContract ? { sandboxExecutionContract } : {}),
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
child = run(invocation.file, invocation.argv, brokerOptions);
|
|
599
|
+
} else if (usePowershell) {
|
|
513
600
|
const { executionPolicy } = loadShellConfig({ cwd: wd });
|
|
514
601
|
const inv = buildPowershellArgv(command, shellKind, { executionPolicy });
|
|
515
602
|
child = run(inv.file, inv.argv, processOptions);
|
package/src/lib/hook-runner.js
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import runner from "./hook-runner.cjs";
|
|
2
2
|
import executionBroker from "./process-execution-broker/index.js";
|
|
3
|
+
import hookShellCommand from "./hook-shell-command.cjs";
|
|
4
|
+
|
|
5
|
+
const {
|
|
6
|
+
issueTrustedHookSandboxContract,
|
|
7
|
+
requireTrustedHookRoot,
|
|
8
|
+
requiresExplicitHookShell,
|
|
9
|
+
sandboxBoundaryError,
|
|
10
|
+
} = hookShellCommand;
|
|
3
11
|
|
|
4
12
|
const brokerRunner = executionBroker.spawn.bind(executionBroker);
|
|
5
13
|
const brokerSyncRunner = executionBroker.spawnSync.bind(executionBroker);
|
|
@@ -17,25 +25,90 @@ function normalizeInvocation(argsOrOptions, maybeOptions) {
|
|
|
17
25
|
|
|
18
26
|
function runHookProcess(file, argsOrOptions, maybeOptions) {
|
|
19
27
|
const { args, options } = normalizeInvocation(argsOrOptions, maybeOptions);
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
const callerOptions = { ...options };
|
|
29
|
+
delete callerOptions.sandboxExecutionContract;
|
|
30
|
+
const processOptions = {
|
|
31
|
+
...callerOptions,
|
|
32
|
+
origin: callerOptions.origin || "hook",
|
|
23
33
|
policy: "allow",
|
|
24
34
|
scope: "hook",
|
|
35
|
+
};
|
|
36
|
+
const requiresContract = requiresExplicitHookShell(
|
|
37
|
+
processOptions.sandboxPolicy,
|
|
38
|
+
);
|
|
39
|
+
const trustedRoot = requiresContract
|
|
40
|
+
? requireTrustedHookRoot(processOptions.cwd)
|
|
41
|
+
: null;
|
|
42
|
+
const sandboxExecutionContract = requiresContract
|
|
43
|
+
? issueTrustedHookSandboxContract({
|
|
44
|
+
issuer: executionBroker.issueLinuxWorkspaceSandboxExecutionContract,
|
|
45
|
+
receiver: executionBroker,
|
|
46
|
+
file,
|
|
47
|
+
args,
|
|
48
|
+
options: processOptions,
|
|
49
|
+
trustedRoot,
|
|
50
|
+
})
|
|
51
|
+
: null;
|
|
52
|
+
if (
|
|
53
|
+
process.platform === "linux" &&
|
|
54
|
+
requiresContract &&
|
|
55
|
+
!sandboxExecutionContract
|
|
56
|
+
) {
|
|
57
|
+
throw sandboxBoundaryError(
|
|
58
|
+
"trusted Linux hook sandbox contract could not be issued",
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
return _processDeps.run(file, args, {
|
|
62
|
+
...processOptions,
|
|
63
|
+
...(sandboxExecutionContract ? { sandboxExecutionContract } : {}),
|
|
25
64
|
});
|
|
26
65
|
}
|
|
27
66
|
|
|
28
67
|
function runHookProcessSync(file, argsOrOptions, maybeOptions) {
|
|
29
68
|
const { args, options } = normalizeInvocation(argsOrOptions, maybeOptions);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
69
|
+
const callerOptions = { ...options };
|
|
70
|
+
delete callerOptions.sandboxExecutionContract;
|
|
71
|
+
const processOptions = {
|
|
72
|
+
...callerOptions,
|
|
73
|
+
origin: callerOptions.origin || "hook",
|
|
33
74
|
policy: "allow",
|
|
34
75
|
scope: "hook",
|
|
76
|
+
};
|
|
77
|
+
const requiresContract = requiresExplicitHookShell(
|
|
78
|
+
processOptions.sandboxPolicy,
|
|
79
|
+
);
|
|
80
|
+
const trustedRoot = requiresContract
|
|
81
|
+
? requireTrustedHookRoot(processOptions.cwd)
|
|
82
|
+
: null;
|
|
83
|
+
const sandboxExecutionContract = requiresContract
|
|
84
|
+
? issueTrustedHookSandboxContract({
|
|
85
|
+
issuer: executionBroker.issueLinuxWorkspaceSandboxExecutionContract,
|
|
86
|
+
receiver: executionBroker,
|
|
87
|
+
file,
|
|
88
|
+
args,
|
|
89
|
+
options: processOptions,
|
|
90
|
+
trustedRoot,
|
|
91
|
+
sync: true,
|
|
92
|
+
})
|
|
93
|
+
: null;
|
|
94
|
+
if (
|
|
95
|
+
process.platform === "linux" &&
|
|
96
|
+
requiresContract &&
|
|
97
|
+
!sandboxExecutionContract
|
|
98
|
+
) {
|
|
99
|
+
throw sandboxBoundaryError(
|
|
100
|
+
"trusted Linux hook sandbox contract could not be issued",
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
return _processDeps.runSync(file, args, {
|
|
104
|
+
...processOptions,
|
|
105
|
+
...(sandboxExecutionContract ? { sandboxExecutionContract } : {}),
|
|
35
106
|
});
|
|
36
107
|
}
|
|
37
108
|
|
|
38
109
|
export function _restoreProcessRunners() {
|
|
110
|
+
_processDeps.run = brokerRunner;
|
|
111
|
+
_processDeps.runSync = brokerSyncRunner;
|
|
39
112
|
runner._deps.run = runHookProcess;
|
|
40
113
|
runner._deps.runSync = runHookProcessSync;
|
|
41
114
|
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
|
|
5
|
+
const STRONG_HOOK_BOUNDARIES = new Set(["filesystem", "network"]);
|
|
6
|
+
|
|
7
|
+
function requiredHookBoundaries(sandboxPolicy) {
|
|
8
|
+
const configured = sandboxPolicy?.requiredBoundaries;
|
|
9
|
+
return Array.isArray(configured) ? configured : [];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function requiresExplicitHookShell(sandboxPolicy) {
|
|
13
|
+
return requiredHookBoundaries(sandboxPolicy).some((boundary) =>
|
|
14
|
+
STRONG_HOOK_BOUNDARIES.has(boundary),
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function sandboxBoundaryError(message) {
|
|
19
|
+
const error = new Error(message);
|
|
20
|
+
error.code = "ERR_PROCESS_SANDBOX_BOUNDARY_UNSATISFIED";
|
|
21
|
+
error.sandboxFailClosed = true;
|
|
22
|
+
return error;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function asSandboxBoundaryError(error, prefix) {
|
|
26
|
+
if (error?.code === "ERR_PROCESS_SANDBOX_BOUNDARY_UNSATISFIED") {
|
|
27
|
+
return error;
|
|
28
|
+
}
|
|
29
|
+
const detail =
|
|
30
|
+
error && typeof error.message === "string" ? error.message : String(error);
|
|
31
|
+
return sandboxBoundaryError(`${prefix}: ${detail}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function issueTrustedHookSandboxContract({
|
|
35
|
+
issuer,
|
|
36
|
+
receiver = null,
|
|
37
|
+
file,
|
|
38
|
+
args,
|
|
39
|
+
options,
|
|
40
|
+
trustedRoot,
|
|
41
|
+
sync = false,
|
|
42
|
+
label = "trusted hook sandbox contract issuance failed",
|
|
43
|
+
}) {
|
|
44
|
+
if (typeof issuer !== "function") return null;
|
|
45
|
+
try {
|
|
46
|
+
return issuer.call(
|
|
47
|
+
receiver,
|
|
48
|
+
file,
|
|
49
|
+
args,
|
|
50
|
+
options,
|
|
51
|
+
trustedRoot,
|
|
52
|
+
...(sync ? [{ sync: true }] : []),
|
|
53
|
+
);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
throw asSandboxBoundaryError(error, label);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function requireTrustedHookRoot(value, label = "hook working directory") {
|
|
60
|
+
if (
|
|
61
|
+
typeof value !== "string" ||
|
|
62
|
+
!value ||
|
|
63
|
+
value.includes("\0") ||
|
|
64
|
+
!path.isAbsolute(value)
|
|
65
|
+
) {
|
|
66
|
+
throw sandboxBoundaryError(
|
|
67
|
+
`${label} must be an absolute trusted path for filesystem/network sandboxing`,
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
return path.resolve(value);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function isPathInside(root, candidate) {
|
|
74
|
+
const relative = path.relative(path.resolve(root), path.resolve(candidate));
|
|
75
|
+
return (
|
|
76
|
+
relative === "" ||
|
|
77
|
+
(relative !== ".." &&
|
|
78
|
+
!relative.startsWith(`..${path.sep}`) &&
|
|
79
|
+
!path.isAbsolute(relative))
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function quotePosixShellArgument(value) {
|
|
84
|
+
const text = String(value);
|
|
85
|
+
if (text.length === 0) return "''";
|
|
86
|
+
return `'${text.replace(/'/g, `'"'"'`)}'`;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function quoteCmdArgument(value) {
|
|
90
|
+
const text = String(value);
|
|
91
|
+
if (text.length === 0) return '""';
|
|
92
|
+
// The command and its arguments are all hook-controlled, but quote cmd.exe
|
|
93
|
+
// metacharacters anyway so an argv entry remains one argument.
|
|
94
|
+
return `"${text
|
|
95
|
+
.replace(/"/g, '""')
|
|
96
|
+
.replace(/([&|<>^])/g, "^$1")
|
|
97
|
+
.replace(/%/g, "%%")}"`;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function appendShellArguments(command, args, platform) {
|
|
101
|
+
if (!Array.isArray(args) || args.length === 0) return command;
|
|
102
|
+
const quote =
|
|
103
|
+
platform === "win32" ? quoteCmdArgument : quotePosixShellArgument;
|
|
104
|
+
return `${command} ${args.map((arg) => quote(arg)).join(" ")}`;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Turn a settings-style shell command into an explicit executable + argv.
|
|
109
|
+
* This is used only when filesystem/network boundaries are requested. Keeping
|
|
110
|
+
* shell selection explicit lets the Broker bind its one-shot contract to the
|
|
111
|
+
* actual launch tuple and guarantees the child spawn itself uses shell:false.
|
|
112
|
+
*/
|
|
113
|
+
function buildExplicitHookShellInvocation(
|
|
114
|
+
command,
|
|
115
|
+
{
|
|
116
|
+
args = [],
|
|
117
|
+
platform = process.platform,
|
|
118
|
+
shellKind = null,
|
|
119
|
+
buildPowershellArgv = null,
|
|
120
|
+
powershellOptions = {},
|
|
121
|
+
} = {},
|
|
122
|
+
) {
|
|
123
|
+
const rendered = appendShellArguments(String(command), args, platform);
|
|
124
|
+
if (
|
|
125
|
+
(shellKind === "powershell" || shellKind === "pwsh") &&
|
|
126
|
+
typeof buildPowershellArgv === "function"
|
|
127
|
+
) {
|
|
128
|
+
return buildPowershellArgv(rendered, shellKind, powershellOptions);
|
|
129
|
+
}
|
|
130
|
+
if (platform === "win32") {
|
|
131
|
+
return {
|
|
132
|
+
file: process.env.ComSpec || "cmd.exe",
|
|
133
|
+
argv: ["/d", "/s", "/c", rendered],
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
return { file: "/bin/sh", argv: ["-c", rendered] };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
module.exports = {
|
|
140
|
+
buildExplicitHookShellInvocation,
|
|
141
|
+
issueTrustedHookSandboxContract,
|
|
142
|
+
isPathInside,
|
|
143
|
+
requireTrustedHookRoot,
|
|
144
|
+
requiredHookBoundaries,
|
|
145
|
+
requiresExplicitHookShell,
|
|
146
|
+
asSandboxBoundaryError,
|
|
147
|
+
sandboxBoundaryError,
|
|
148
|
+
};
|