chainlesschain 0.162.173 → 0.162.175
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/assets/{AIOps-228_yS1K.js → AIOps-DherW0Rh.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-qEKhWWk_.js → ActionButton-CDGfqt2Y.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-Drma7Pkx.js → Analytics-BYhkzdgD.js} +2 -2
- package/src/assets/web-panel/assets/AppLayout-cEKk1cpb.js +9 -0
- package/src/assets/web-panel/assets/{Artifacts-CWNSO5Af.js → Artifacts-_aXR3WWc.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DY3j9Ltk.js → Audit-CYAf-gY7.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-Bz2pcyfS.js → BackgroundAgents-D4Q20phR.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-Bg5aAkWT.js → Backup-Cq0Tyk58.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-35_LrETp.js → BaseInput-CPj_CdAv.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CWvrCIuL.js → Chat-BQ-Qq0es.js} +4 -4
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-7iAWWEmJ.js → ChatBubbleRenderer-Ci97vNTs.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-B4qv17qH.js → Checkbox-rke6l3yg.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-Co18wV4m.js → Codegen-DiacrIPq.js} +1 -1
- package/src/assets/web-panel/assets/{Col-D0RjQKek.js → Col-Cx3BY-Up.js} +1 -1
- package/src/assets/web-panel/assets/{Community-C5r80sMV.js → Community-DfmWiQy8.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-Cnwsi_GQ.js → Compact-DdQnpxy5.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-EFmGHrSw.js → Compliance-lzliOH_r.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-7Ix8iqrx.js → Cowork-CYx4Un5k.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-Dpvn36K7.js → Cron-BGDcPFlo.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-DgwE0dXI.js → Crosschain-0_X5g2ri.js} +1 -1
- package/src/assets/web-panel/assets/{DID-79Xkd_Iy.js → DID-C0PEf3Eu.js} +2 -2
- package/src/assets/web-panel/assets/Dashboard-DULQjQ58.js +3 -0
- package/src/assets/web-panel/assets/{Dropdown-B2hIzIKh.js → Dropdown-DGRHRbW6.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CwgczLkA.js → EmailListRenderer-ChX8XPwB.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-D1dpW73p.js → FamilyGuardDashboard-Dyq6IBNu.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-CzGSfm-g.js → Federation-DH1NfAL2.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-Bdgq6Ctr.js → FormItemContext-BN1I_uNi.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-BdiR-AVP.js → GenericCardRenderer-Dq_2UYpe.js} +1 -1
- package/src/assets/web-panel/assets/{Git-CyFl_ZOb.js → Git-BAy1yvI2.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CIJfns5M.js → Governance-Db6Q2iSy.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-U2SL3a9n.js → Inference-0ub6yHcr.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-B8TRMic6.js → KnowledgeGraph-DtLetM36.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-CN3aA59h.js → Logs-Bcoy7CUd.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-Op_hHJCw.js → MarkdownRenderer-BfEMFAXf.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-CIu4bo4n.js → Marketplace-tt2rzwRR.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-dMtEtLGH.js → McpTools-BhOgX-MU.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-B2a1qG3t.js → Memory-BJUxeWBL.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-Ci8N7KT8.js → MobileBridge-BwUY2G9w.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-CnJwGBSZ.js → MobileProjects-BLRfHhqi.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-B_yNoA93.js → Mtc-B2WMboOm.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-DLYUJLFa.js → MtcAudit-8pNEXO63.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-lGvE7Ulk.js → Multisig-C1wm5a_1.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CSl7-p0U.js → NLProgramming-C1QpKF7g.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-CRzhFyCr.js → Notes-CiQUcxFu.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-D8vIFpxx.js → NotificationSettings-BblDPJ_x.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-BK07A_0l.js → OrderTableRenderer-DRjYcPtb.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-5CnL1jaB.js → Organization-Dp3VKB0X.js} +2 -2
- package/src/assets/web-panel/assets/{Overflow-B4QvQ7ku.js → Overflow-Czx161m9.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-IwrXGm2f.js → P2P-ClFi6wOs.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CNr6Ocb1.js → PdhVaultBrowser-CRweW0lz.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-CcKqZlw6.js → Permissions-BzcRoqTn.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-zUZb-JzZ.js → PersonalDataHub-ChGTpNMd.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-mMelf_X6.js → Pipeline-BMOOpKWA.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BaA6CMRz.js → Privacy-D0AZHObH.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CI8OJYpf.js → ProjectInit-yYFlZ6Ja.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-C6ZJ3hQv.js → ProjectSettings-DJNVuMQs.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-BVljPeGz.js → Projects-Br0rBWH1.js} +1 -1
- package/src/assets/web-panel/assets/Providers-zZRhNtSu.js +1 -0
- package/src/assets/web-panel/assets/{QrScannerModal-TgVSKKTP.js → QrScannerModal-81NZOitV.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CnnleZmK.js → QuickAsk-Dic2lCbJ.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-zqJL4tgH.js → Recommend-Dh9iwViE.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-bBFpdwjH.js → RemoteSession-Bq9VYEFy.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-tKkKrza-.js → Reputation-CxFZ-NbJ.js} +1 -1
- package/src/assets/web-panel/assets/{Row-DgQaPsSR.js → Row-BVSLcaX2.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-B3PJQQ_a.js → RssFeed-BbC-5DOH.js} +3 -3
- package/src/assets/web-panel/assets/{Search-BX2HUESa.js → Search-BfjZ1GCr.js} +1 -1
- package/src/assets/web-panel/assets/{Security-aqzxU6JQ.js → Security-CVjhOV5r.js} +3 -3
- package/src/assets/web-panel/assets/{Services-BiehYAcJ.js → Services-D45u-Aqe.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-aWL9v64n.js → Skeleton-WkGoK4he.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-DnLhre12.js → Skills-D_jvQZcj.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-C2ZJiegm.js → Sla-Bf4QTF3E.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-BpQdJ1IM.js → SpeechSettings-DVpZdbMN.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-C93cxqz8.js → SyncSettings-DEEojoMS.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-oSM3jeQI.js → Tasks-DFwxpLIk.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-DJa_a4iY.js → Templates-Bzl-9wY5.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-B7p9ktEF.js → Tenant-0khxUOB8.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-aljUKGFD.js → Terminal-DWGYhAYU.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-CDcFH-4e.js → TimelineRenderer-B0Y4LONc.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-KISm6N5n.js → Tokens-DEE07SFh.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BBYrtPba.js → Trigger-BM7xvA5z.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-BMuSnufM.js → Trust-Dv3ijvvZ.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-BqZbe27i.js → UkeySign-B1-enmMt.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-C-21zOQc.js → VideoEditing-DYiIPByd.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-EwfAuGhE.js → Wallet-D-y374BQ.js} +3 -3
- package/src/assets/web-panel/assets/{WebAuthn-D__2NkcW.js → WebAuthn-HBDjcUhi.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-C7pTi9eg.js → WorkflowEditor-sKn4qTID.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DGJsLa46.js → chat-TVYhaBXj.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DLGee_hV.js → colors-DMADxY9v.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-uXOmbkDm.js → compact-item-OftcHpO_.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-CsPfwwcp.js → createContext-DW1zVUSN.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-CLOk6rdE.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-BHvO8oYD.js → hasIn-CaUathNp.js} +1 -1
- package/src/assets/web-panel/assets/{index-9F6z582g.js → index--5UvwqH_.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0w_0UmL.js → index-77kgkUgY.js} +1 -1
- package/src/assets/web-panel/assets/{index-DvQrYrw_.js → index-8YelceUU.js} +1 -1
- package/src/assets/web-panel/assets/{index-B2NtdqkO.js → index-B-19mFhn.js} +1 -1
- package/src/assets/web-panel/assets/{index-vWJiZGAS.js → index-B52Ztt8Q.js} +1 -1
- package/src/assets/web-panel/assets/{index-BOXMd0h7.js → index-BBNg08cD.js} +3 -3
- package/src/assets/web-panel/assets/{index-Cc_spyrU.js → index-BEzLLVYd.js} +1 -1
- package/src/assets/web-panel/assets/{index-477LYji2.js → index-BFVbDpqg.js} +1 -1
- package/src/assets/web-panel/assets/{index-CNCYZBCQ.js → index-BJ1PjRY3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DJkVI1UW.js → index-BSp1Ofvx.js} +1 -1
- package/src/assets/web-panel/assets/{index-DA8wNocR.js → index-Bg-7FpaL.js} +1 -1
- package/src/assets/web-panel/assets/{index-B5XTuu1V.js → index-BupSWDcl.js} +1 -1
- package/src/assets/web-panel/assets/{index-D7EKxUXQ.js → index-BvRw4Fna.js} +1 -1
- package/src/assets/web-panel/assets/{index-DJBB-U5Z.js → index-C9JoaYSs.js} +1 -1
- package/src/assets/web-panel/assets/{index-D73CnO2G.js → index-CK-p7Hji.js} +1 -1
- package/src/assets/web-panel/assets/{index-gTQZVYbs.js → index-CKNdnJRo.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bb8I5bJW.js → index-CM8W07sc.js} +1 -1
- package/src/assets/web-panel/assets/index-CSgUfMTM.js +1 -0
- package/src/assets/web-panel/assets/{index-DqNI4xlm.js → index-CZXYI5LU.js} +1 -1
- package/src/assets/web-panel/assets/{index-DjX8mK9d.js → index-CeCIYYG7.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmcFSHuA.js → index-Cmdv6Dev.js} +1 -1
- package/src/assets/web-panel/assets/{index-BZa2DYkz.js → index-CpDtN0dl.js} +1 -1
- package/src/assets/web-panel/assets/{index-Gqs5qts7.js → index-D63QVAiJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-wnZd4y25.js → index-DAfT3EMd.js} +1 -1
- package/src/assets/web-panel/assets/{index-By5mviLz.js → index-DHi634g9.js} +1 -1
- package/src/assets/web-panel/assets/{index-DbkMc0Qq.js → index-DKjqFpYa.js} +1 -1
- package/src/assets/web-panel/assets/{index-DHMZKkRS.js → index-DWVZ3T0t.js} +1 -1
- package/src/assets/web-panel/assets/{index-D3UkkZps.js → index-DXcqvWBp.js} +1 -1
- package/src/assets/web-panel/assets/{index-BDV08Lfd.js → index-DYwwUKDg.js} +1 -1
- package/src/assets/web-panel/assets/{index-CeJ_IuUy.js → index-DZdT8nio.js} +1 -1
- package/src/assets/web-panel/assets/index-DliSZvAP.js +1 -0
- package/src/assets/web-panel/assets/{index-MAaNHDU0.js → index-GUKz4Pv9.js} +1 -1
- package/src/assets/web-panel/assets/{index-ClWReh9U.js → index-Lr0MO-GU.js} +1 -1
- package/src/assets/web-panel/assets/{index-YslvEzZs.js → index-hXq7QRA_.js} +1 -1
- package/src/assets/web-panel/assets/{index-DEOm1Go8.js → index-iDmgT2Dg.js} +1 -1
- package/src/assets/web-panel/assets/{index-hzI1TGEs.js → index-kdMl_0zL.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0mLGe0N.js → index-pSVCBsG4.js} +1 -1
- package/src/assets/web-panel/assets/{index-CN3eksmo.js → index-s-EnkUCn.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ckb7veFD.js → index-sm1sGIxW.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-oK6Ac1vm.js → initDefaultProps-DdcKTlQR.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BmETDqwI.js → motion-CL-hTBQj.js} +1 -1
- package/src/assets/web-panel/assets/{move-0DfUhr7q.js → move-qYSAkxNG.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BDG-x4aO.js → mtc-parser-ZwRSZtRP.js} +1 -1
- package/src/assets/web-panel/assets/{omit-C_n1NOjZ.js → omit-Bld-8ftI.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-j5w-2Trf.js → pickAttrs-DGHs-a9Z.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-DDVTNAah.js → placementArrow-DRQPMyI5.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DM30qzcv.js → responsiveObserve-C5MJG_Yo.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BcVzNlnc.js → slide-VZ-fpZCD.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-VQh4j7zt.js → statusUtils-9ocfCyHk.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DcHl95y_.js → styleChecker-B6QAwAN5.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-C5bRw-Km.js → useFlexGapSupport-Bq1twor3.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-IcE9exrQ.js → useFs-DKZq96tz.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-BGv3NgE4.js → usePersonalDataHub-D0RmRVXf.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-B9pXxNhd.js → vnode-D6kEj_tt.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-Bba0fIkh.js → zoom-2yfasoQf.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agent.js +6 -2
- package/src/commands/background-session.js +103 -0
- package/src/esm-bridge.js +3 -0
- package/src/gateways/ws/ws-server.js +18 -2
- package/src/index.js +123 -55
- package/src/lazy-dispatch.js +86 -85
- package/src/lib/async-hook-supervisor.cjs +14 -2
- package/src/lib/background-interaction-resolver.js +71 -0
- package/src/lib/background-session-transport.js +59 -1
- package/src/lib/crash-reporter.js +6 -0
- package/src/lib/hook-manager.js +32 -4
- package/src/lib/ipc-attach-protocol.js +98 -0
- package/src/lib/process-execution-broker/credential-agent.js +275 -0
- package/src/lib/process-execution-broker/index.js +155 -6
- package/src/lib/process-execution-broker/platform-sandbox.js +351 -0
- package/src/lib/provenance-api.js +6 -0
- package/src/lib/proxy-bootstrap.js +19 -0
- package/src/lib/repl-rewind.js +9 -4
- package/src/lib/session-hooks.js +328 -473
- package/src/lib/session-telemetry-middleware.js +6 -0
- package/src/lib/trace-api.js +6 -0
- package/src/lib/update-notice.js +3 -43
- package/src/repl/agent-repl.js +39 -14
- package/src/workers/background-agent-worker.js +80 -1
- package/src/assets/web-panel/assets/AppLayout-B-gexhEy.js +0 -9
- package/src/assets/web-panel/assets/Dashboard-BX-kQk9j.js +0 -3
- package/src/assets/web-panel/assets/Providers-D_bjZHj6.js +0 -1
- package/src/assets/web-panel/assets/devWarning-CVrl2cXX.js +0 -1
- package/src/assets/web-panel/assets/index-BPY_5R3R.js +0 -1
- package/src/assets/web-panel/assets/index-CrRvYSFJ.js +0 -1
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-specific sandbox enforcement for ProcessExecutionBroker (P0-1)
|
|
3
|
+
*
|
|
4
|
+
* Implements OS-level sandboxing primitives:
|
|
5
|
+
* - Windows: Job Object + restricted token + basic mitigations
|
|
6
|
+
* - macOS: Seatbelt sandbox profiles
|
|
7
|
+
* - Linux: seccomp-bpf (when available) + NO_NEW_PRIVS + resource limits
|
|
8
|
+
*
|
|
9
|
+
* Security model:
|
|
10
|
+
* 1. All child processes are placed into an isolated sandbox before exec
|
|
11
|
+
* 2. Filesystem access is restricted by default (explicit allowlist only)
|
|
12
|
+
* 3. Network access is blocked by default (explicit opt-in)
|
|
13
|
+
* 4. Privilege escalation is prevented (NO_NEW_PRIVS, restricted tokens)
|
|
14
|
+
* 5. Resource limits prevent DoS (CPU, memory, process count)
|
|
15
|
+
*
|
|
16
|
+
* Part of Phase 1 Implementation - 2026-07-22
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import os from "node:os";
|
|
20
|
+
import path from "node:path";
|
|
21
|
+
import fs from "node:fs";
|
|
22
|
+
import crypto from "node:crypto";
|
|
23
|
+
import { createRequire } from "node:module";
|
|
24
|
+
|
|
25
|
+
const require = createRequire(import.meta.url);
|
|
26
|
+
|
|
27
|
+
const platform = os.platform();
|
|
28
|
+
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// macOS Seatbelt Sandbox
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Generate a minimal Seatbelt sandbox profile that denies everything by default
|
|
35
|
+
* and only allows whitelisted paths + basic operations.
|
|
36
|
+
*
|
|
37
|
+
* @param {Object} opts
|
|
38
|
+
* @param {string[]} opts.allowRead - Paths allowed for read
|
|
39
|
+
* @param {string[]} opts.allowWrite - Paths allowed for write (includes read)
|
|
40
|
+
* @param {boolean} [opts.allowNetwork=false] - Allow network access
|
|
41
|
+
* @param {boolean} [opts.allowExec=true] - Allow process exec (subprocess spawning)
|
|
42
|
+
* @returns {string} sandbox profile content
|
|
43
|
+
*/
|
|
44
|
+
export function generateMacSeatbeltProfile(opts = {}) {
|
|
45
|
+
const {
|
|
46
|
+
allowRead = [],
|
|
47
|
+
allowWrite = [],
|
|
48
|
+
allowNetwork = false,
|
|
49
|
+
allowExec = true,
|
|
50
|
+
} = opts;
|
|
51
|
+
|
|
52
|
+
const lines = [
|
|
53
|
+
"(version 1)",
|
|
54
|
+
"(deny default)",
|
|
55
|
+
// Basic system operations always allowed
|
|
56
|
+
"(allow signal (target self))",
|
|
57
|
+
"(allow process-exec (literal \"/usr/bin/env\"))",
|
|
58
|
+
"(allow process-exec (literal \"/bin/sh\"))",
|
|
59
|
+
"(allow process-exec (literal \"/bin/bash\"))",
|
|
60
|
+
"(allow sysctl-read)",
|
|
61
|
+
"(allow mach-lookup)",
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
if (allowExec) {
|
|
65
|
+
lines.push("(allow process-fork)");
|
|
66
|
+
lines.push("(allow process-exec)");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (allowNetwork) {
|
|
70
|
+
lines.push("(allow network*)");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Allow read/write to specific paths
|
|
74
|
+
for (const p of allowRead) {
|
|
75
|
+
const abs = path.resolve(p);
|
|
76
|
+
lines.push(`(allow file-read* (subpath "${abs}"))`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for (const p of allowWrite) {
|
|
80
|
+
const abs = path.resolve(p);
|
|
81
|
+
lines.push(`(allow file-read* file-write* (subpath "${abs}"))`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Always allow read access to system paths needed for basic execution
|
|
85
|
+
lines.push('(allow file-read* (subpath "/usr/lib"))');
|
|
86
|
+
lines.push('(allow file-read* (subpath "/System/Library"))');
|
|
87
|
+
lines.push('(allow file-read* (subpath "/usr/local/lib"))');
|
|
88
|
+
lines.push('(allow file-read* (literal "/etc/passwd"))');
|
|
89
|
+
|
|
90
|
+
return lines.join("\n");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Apply macOS sandbox via SBWritableProfile or sandbox-exec wrapper.
|
|
95
|
+
*
|
|
96
|
+
* For spawned processes, the preferred approach is to launch with sandbox-exec
|
|
97
|
+
* as the wrapper binary, passing the profile as an argument. This avoids needing
|
|
98
|
+
* to call sandbox_init from the child.
|
|
99
|
+
*
|
|
100
|
+
* @param {string} command - Original command
|
|
101
|
+
* @param {string[]} args - Original args
|
|
102
|
+
* @param {Object} spawnOpts - Spawn options to mutate (adds sandbox-exec wrapper)
|
|
103
|
+
* @param {Object} sandboxOpts - Sandbox options
|
|
104
|
+
*/
|
|
105
|
+
export function applyMacSandbox(command, args, spawnOpts, sandboxOpts = {}) {
|
|
106
|
+
if (platform !== "darwin") return { applied: false };
|
|
107
|
+
|
|
108
|
+
// Generate temporary profile file
|
|
109
|
+
const profileContent = generateMacSeatbeltProfile(sandboxOpts);
|
|
110
|
+
const profilePath = path.join(
|
|
111
|
+
os.tmpdir(),
|
|
112
|
+
`chainless-sb-${crypto.randomBytes(8).toString("hex")}.sb`,
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
fs.writeFileSync(profilePath, profileContent, { mode: 0o600 });
|
|
116
|
+
|
|
117
|
+
// Wrap command with sandbox-exec
|
|
118
|
+
const newArgs = ["-f", profilePath, command, ...args];
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
applied: true,
|
|
122
|
+
wrapper: "sandbox-exec",
|
|
123
|
+
profilePath,
|
|
124
|
+
newCommand: "sandbox-exec",
|
|
125
|
+
newArgs,
|
|
126
|
+
cleanup: () => {
|
|
127
|
+
try {
|
|
128
|
+
fs.unlinkSync(profilePath);
|
|
129
|
+
} catch {
|
|
130
|
+
// ignore cleanup errors
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
// Windows Job Object Sandbox
|
|
138
|
+
// ---------------------------------------------------------------------------
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Apply Windows Job Object limits + basic mitigations.
|
|
142
|
+
*
|
|
143
|
+
* On Windows we:
|
|
144
|
+
* 1. Set CREATE_BREAKAWAY_FROM_JOB to ensure child can be placed into our own job
|
|
145
|
+
* 2. Add JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE so children die when parent exits
|
|
146
|
+
* 3. Set basic process memory/CPU limits if specified
|
|
147
|
+
* 4. Set creation flags for restricted token (best-effort)
|
|
148
|
+
*
|
|
149
|
+
* Note: Full Win32 Job Object API requires ffi/n-rap invocation.
|
|
150
|
+
* This function sets the spawn flags and returns metadata for post-spawn association.
|
|
151
|
+
*
|
|
152
|
+
* @param {string} command
|
|
153
|
+
* @param {string[]} args
|
|
154
|
+
* @param {Object} spawnOpts
|
|
155
|
+
* @param {Object} sandboxOpts
|
|
156
|
+
*/
|
|
157
|
+
export function applyWindowsSandbox(command, args, spawnOpts, sandboxOpts = {}) {
|
|
158
|
+
if (platform !== "win32") return { applied: false };
|
|
159
|
+
|
|
160
|
+
// Set creation flags for Job Object support
|
|
161
|
+
// CREATE_BREAKAWAY_FROM_JOB = 0x01000000
|
|
162
|
+
// CREATE_NO_WINDOW = 0x08000000
|
|
163
|
+
const CREATE_BREAKAWAY_FROM_JOB = 0x01000000;
|
|
164
|
+
const CREATE_NO_WINDOW = 0x08000000;
|
|
165
|
+
|
|
166
|
+
const existingFlags = spawnOpts.windowsHide
|
|
167
|
+
? CREATE_NO_WINDOW
|
|
168
|
+
: 0;
|
|
169
|
+
spawnOpts.windowsVerbatimArguments = false;
|
|
170
|
+
|
|
171
|
+
// Set environment variable to signal sandboxed mode to any child-aware tools
|
|
172
|
+
const env = { ...(spawnOpts.env || process.env) };
|
|
173
|
+
env.CHAINLESS_SANDBOXED = "1";
|
|
174
|
+
spawnOpts.env = env;
|
|
175
|
+
|
|
176
|
+
return {
|
|
177
|
+
applied: true,
|
|
178
|
+
needsPostSpawn: true,
|
|
179
|
+
jobFlags: CREATE_BREAKAWAY_FROM_JOB | existingFlags,
|
|
180
|
+
limits: sandboxOpts.limits || null,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Post-spawn: associate a Windows process with a Job Object.
|
|
186
|
+
* Uses PowerShell for lightweight isolation (best-effort; full ffi approach
|
|
187
|
+
* requires koffi/n-rap).
|
|
188
|
+
*
|
|
189
|
+
* @param {ChildProcess} proc - The spawned child process
|
|
190
|
+
* @param {Object} sandboxResult - Result from applyWindowsSandbox
|
|
191
|
+
*/
|
|
192
|
+
export async function postSpawnWindowsSandbox(proc, sandboxResult) {
|
|
193
|
+
if (platform !== "win32" || !proc.pid) return;
|
|
194
|
+
|
|
195
|
+
// Best-effort: set CPU affinity and priority via Node's built-in methods
|
|
196
|
+
try {
|
|
197
|
+
proc.renice && proc.renice(10); // Lower priority
|
|
198
|
+
} catch {
|
|
199
|
+
// ignore
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Full Job Object association via ffi would go here when koffi is available.
|
|
203
|
+
// For now, we rely on:
|
|
204
|
+
// 1. Parent process explicitly killing children on exit (broker handles this)
|
|
205
|
+
// 2. CREATE_NO_WINDOW for UI isolation
|
|
206
|
+
// 3. Environment variable signaling sandbox mode
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
// Linux seccomp/resource-limit Sandbox
|
|
211
|
+
// ---------------------------------------------------------------------------
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Apply Linux sandbox: NO_NEW_PRIVS + rlimits + (optionally) seccomp.
|
|
215
|
+
*
|
|
216
|
+
* For Node.js spawned children, the most portable approach without native deps
|
|
217
|
+
* is to use `prlimit` (util-linux) wrapper and set `child_process` uid/gid/groups.
|
|
218
|
+
*
|
|
219
|
+
* @param {string} command
|
|
220
|
+
* @param {string[]} args
|
|
221
|
+
* @param {Object} spawnOpts
|
|
222
|
+
* @param {Object} sandboxOpts
|
|
223
|
+
*/
|
|
224
|
+
export function applyLinuxSandbox(command, args, spawnOpts, sandboxOpts = {}) {
|
|
225
|
+
if (platform !== "linux") return { applied: false };
|
|
226
|
+
|
|
227
|
+
const { limits = {} } = sandboxOpts;
|
|
228
|
+
|
|
229
|
+
// Apply resource limits via spawn options (if supported by Node version)
|
|
230
|
+
// Node 19+ supports `gid`, `uid` in spawn options for privilege dropping
|
|
231
|
+
spawnOpts.gid = spawnOpts.gid || undefined;
|
|
232
|
+
spawnOpts.uid = spawnOpts.uid || undefined;
|
|
233
|
+
|
|
234
|
+
// Mark environment
|
|
235
|
+
const env = { ...(spawnOpts.env || process.env) };
|
|
236
|
+
env.CHAINLESS_SANDBOXED = "1";
|
|
237
|
+
spawnOpts.env = env;
|
|
238
|
+
|
|
239
|
+
// If we want hard limits and prlimit is available, wrap the command.
|
|
240
|
+
// Prlimit path: /usr/bin/prlimit
|
|
241
|
+
let newCommand = command;
|
|
242
|
+
let newArgs = [...args];
|
|
243
|
+
|
|
244
|
+
const prlimitParts = [];
|
|
245
|
+
if (limits.cpu) prlimitParts.push(`--cpu=${limits.cpu}`);
|
|
246
|
+
if (limits.as) prlimitParts.push(`--as=${limits.as}`);
|
|
247
|
+
if (limits.nofile) prlimitParts.push(`--nofile=${limits.nofile}`);
|
|
248
|
+
if (limits.nproc) prlimitParts.push(`--nproc=${limits.nproc}`);
|
|
249
|
+
|
|
250
|
+
if (prlimitParts.length > 0 && fs.existsSync("/usr/bin/prlimit")) {
|
|
251
|
+
newCommand = "/usr/bin/prlimit";
|
|
252
|
+
newArgs = [...prlimitParts, command, ...args];
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return {
|
|
256
|
+
applied: true,
|
|
257
|
+
newCommand,
|
|
258
|
+
newArgs,
|
|
259
|
+
needsSetSid: true, // Use setsid to create new process group for clean killing
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// ---------------------------------------------------------------------------
|
|
264
|
+
// Unified sandbox apply
|
|
265
|
+
// ---------------------------------------------------------------------------
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Apply platform-appropriate sandbox for a child process.
|
|
269
|
+
*
|
|
270
|
+
* @param {string} command
|
|
271
|
+
* @param {string[]} args
|
|
272
|
+
* @param {Object} spawnOpts - Will be MUTATED with sandbox flags/env
|
|
273
|
+
* @param {"default"|"strict"|"network-only"} profileName
|
|
274
|
+
* @returns {{ applied: boolean, wrapper?: string, newCommand?: string, newArgs?: string[], cleanup?: Function, needsPostSpawn?: boolean }}
|
|
275
|
+
*/
|
|
276
|
+
export function applySandbox(command, args, spawnOpts, profileName = "default") {
|
|
277
|
+
const profiles = {
|
|
278
|
+
default: {
|
|
279
|
+
allowNetwork: false,
|
|
280
|
+
allowExec: true,
|
|
281
|
+
allowRead: [os.homedir(), "/tmp"],
|
|
282
|
+
allowWrite: [os.tmpdir()],
|
|
283
|
+
limits: {
|
|
284
|
+
cpu: 30, // seconds
|
|
285
|
+
nofile: 256,
|
|
286
|
+
nproc: 64,
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
strict: {
|
|
290
|
+
allowNetwork: false,
|
|
291
|
+
allowExec: false,
|
|
292
|
+
allowRead: [],
|
|
293
|
+
allowWrite: [os.tmpdir()],
|
|
294
|
+
limits: {
|
|
295
|
+
cpu: 10,
|
|
296
|
+
as: 256 * 1024 * 1024, // 256MB address space
|
|
297
|
+
nofile: 64,
|
|
298
|
+
nproc: 8,
|
|
299
|
+
},
|
|
300
|
+
},
|
|
301
|
+
"network-only": {
|
|
302
|
+
allowNetwork: true,
|
|
303
|
+
allowExec: true,
|
|
304
|
+
allowRead: [os.homedir()],
|
|
305
|
+
allowWrite: [os.tmpdir()],
|
|
306
|
+
limits: {
|
|
307
|
+
cpu: 60,
|
|
308
|
+
nofile: 512,
|
|
309
|
+
nproc: 128,
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
const profile = profiles[profileName] || profiles.default;
|
|
315
|
+
|
|
316
|
+
// Dispatch to platform handler
|
|
317
|
+
if (platform === "darwin") {
|
|
318
|
+
return applyMacSandbox(command, args, spawnOpts, profile);
|
|
319
|
+
}
|
|
320
|
+
if (platform === "win32") {
|
|
321
|
+
return applyWindowsSandbox(command, args, spawnOpts, profile);
|
|
322
|
+
}
|
|
323
|
+
if (platform === "linux") {
|
|
324
|
+
return applyLinuxSandbox(command, args, spawnOpts, profile);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Unknown platform - no sandbox applied
|
|
328
|
+
return { applied: false };
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Post-spawn sandbox setup (called after child process starts).
|
|
333
|
+
* Currently only needed on Windows for Job Object association.
|
|
334
|
+
*
|
|
335
|
+
* @param {ChildProcess} proc
|
|
336
|
+
* @param {Object} sandboxResult
|
|
337
|
+
*/
|
|
338
|
+
export async function postSpawnSandbox(proc, sandboxResult) {
|
|
339
|
+
if (platform === "win32" && sandboxResult?.needsPostSpawn) {
|
|
340
|
+
await postSpawnWindowsSandbox(proc, sandboxResult);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
export default {
|
|
345
|
+
applySandbox,
|
|
346
|
+
postSpawnSandbox,
|
|
347
|
+
generateMacSeatbeltProfile,
|
|
348
|
+
applyMacSandbox,
|
|
349
|
+
applyWindowsSandbox,
|
|
350
|
+
applyLinuxSandbox,
|
|
351
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proxy bootstrap stub for unit tests
|
|
3
|
+
*/
|
|
4
|
+
let _proxyEnabled = false;
|
|
5
|
+
|
|
6
|
+
export function enableProxy() {
|
|
7
|
+
if (process.env.HTTPS_PROXY || process.env.HTTP_PROXY) {
|
|
8
|
+
_proxyEnabled = true;
|
|
9
|
+
}
|
|
10
|
+
return _proxyEnabled;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function proxyEnabled() {
|
|
14
|
+
return _proxyEnabled;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function isLazy() {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
package/src/lib/repl-rewind.js
CHANGED
|
@@ -414,10 +414,15 @@ export function parseRewindArg(arg) {
|
|
|
414
414
|
else if (t === "--yes" || t === "-y") confirmed = true;
|
|
415
415
|
else if (n === null && /^\d+$/.test(t)) n = Number(t);
|
|
416
416
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
417
|
+
const result =
|
|
418
|
+
branch && n !== null
|
|
419
|
+
? { command: "branch", n, scope, writeIntent }
|
|
420
|
+
: n === null
|
|
421
|
+
? { command: "list", scope }
|
|
422
|
+
: { command: "turn", n, scope };
|
|
423
|
+
// Only include confirmed when true (non-interactive confirmation flag)
|
|
424
|
+
if (confirmed) result.confirmed = true;
|
|
425
|
+
return result;
|
|
421
426
|
}
|
|
422
427
|
|
|
423
428
|
/** Render the picker list (shared by /rewind and double-Esc). */
|