@google/gemini-cli-core 0.35.0-preview.2 → 0.36.0-nightly.20260321.fc03891a1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/dist/docs/CONTRIBUTING.md +0 -15
- package/dist/docs/admin/enterprise-controls.md +61 -0
- package/dist/docs/changelogs/index.md +11 -0
- package/dist/docs/changelogs/latest.md +459 -209
- package/dist/docs/changelogs/preview.md +355 -454
- package/dist/docs/cli/checkpointing.md +3 -1
- package/dist/docs/cli/cli-reference.md +1 -0
- package/dist/docs/cli/custom-commands.md +7 -5
- package/dist/docs/cli/enterprise.md +15 -9
- package/dist/docs/cli/git-worktrees.md +107 -0
- package/dist/docs/cli/model-steering.md +4 -3
- package/dist/docs/cli/model.md +3 -1
- package/dist/docs/cli/notifications.md +4 -3
- package/dist/docs/cli/plan-mode.md +28 -8
- package/dist/docs/cli/sandbox.md +24 -4
- package/dist/docs/cli/session-management.md +6 -0
- package/dist/docs/cli/settings.md +14 -1
- package/dist/docs/cli/skills.md +4 -2
- package/dist/docs/cli/system-prompt.md +3 -1
- package/dist/docs/cli/telemetry.md +6 -3
- package/dist/docs/cli/themes.md +12 -8
- package/dist/docs/cli/tutorials/file-management.md +8 -6
- package/dist/docs/cli/tutorials/mcp-setup.md +5 -3
- package/dist/docs/cli/tutorials/memory-management.md +6 -6
- package/dist/docs/cli/tutorials/plan-mode-steering.md +4 -3
- package/dist/docs/cli/tutorials/shell-commands.md +3 -3
- package/dist/docs/core/remote-agents.md +8 -3
- package/dist/docs/core/subagents.md +21 -13
- package/dist/docs/extensions/reference.md +8 -3
- package/dist/docs/get-started/authentication.md +60 -50
- package/dist/docs/get-started/examples.md +3 -1
- package/dist/docs/get-started/gemini-3.md +11 -5
- package/dist/docs/hooks/index.md +3 -1
- package/dist/docs/hooks/writing-hooks.md +2 -2
- package/dist/docs/ide-integration/ide-companion-spec.md +5 -3
- package/dist/docs/ide-integration/index.md +8 -4
- package/dist/docs/issue-and-pr-automation.md +3 -1
- package/dist/docs/local-development.md +3 -1
- package/dist/docs/reference/commands.md +2 -2
- package/dist/docs/reference/configuration.md +410 -16
- package/dist/docs/reference/policy-engine.md +47 -19
- package/dist/docs/reference/tools.md +3 -1
- package/dist/docs/release-confidence.md +7 -3
- package/dist/docs/releases.md +11 -7
- package/dist/docs/resources/faq.md +13 -0
- package/dist/docs/resources/tos-privacy.md +4 -2
- package/dist/docs/resources/troubleshooting.md +3 -1
- package/dist/docs/sidebar.json +5 -0
- package/dist/docs/tools/mcp-server.md +17 -9
- package/dist/docs/tools/planning.md +3 -1
- package/dist/docs/tools/shell.md +4 -4
- package/dist/docs/tools/todos.md +2 -1
- package/dist/{google-gemini-cli-core-0.35.0-preview.1.tgz → google-gemini-cli-core-0.36.0-nightly.20260317.2f90b4653.tgz} +0 -0
- package/dist/src/agent/agent-session.d.ts +37 -0
- package/dist/src/agent/agent-session.js +168 -0
- package/dist/src/agent/agent-session.js.map +1 -0
- package/dist/src/agent/agent-session.test.d.ts +6 -0
- package/dist/src/agent/agent-session.test.js +217 -0
- package/dist/src/agent/agent-session.test.js.map +1 -0
- package/dist/src/agent/content-utils.d.ts +33 -0
- package/dist/src/agent/content-utils.js +135 -0
- package/dist/src/agent/content-utils.js.map +1 -0
- package/dist/src/agent/content-utils.test.d.ts +6 -0
- package/dist/src/agent/content-utils.test.js +223 -0
- package/dist/src/agent/content-utils.test.js.map +1 -0
- package/dist/src/agent/mock.d.ts +9 -12
- package/dist/src/agent/mock.js +88 -129
- package/dist/src/agent/mock.js.map +1 -1
- package/dist/src/agent/mock.test.js +114 -144
- package/dist/src/agent/mock.test.js.map +1 -1
- package/dist/src/agent/types.d.ts +21 -21
- package/dist/src/agents/a2a-client-manager.d.ts +2 -11
- package/dist/src/agents/a2a-client-manager.js +3 -19
- package/dist/src/agents/a2a-client-manager.js.map +1 -1
- package/dist/src/agents/a2a-client-manager.test.js +6 -10
- package/dist/src/agents/a2a-client-manager.test.js.map +1 -1
- package/dist/src/agents/agent-scheduler.d.ts +6 -0
- package/dist/src/agents/agent-scheduler.js +3 -2
- package/dist/src/agents/agent-scheduler.js.map +1 -1
- package/dist/src/agents/agent-scheduler.test.js +6 -0
- package/dist/src/agents/agent-scheduler.test.js.map +1 -1
- package/dist/src/agents/browser/browserAgentDefinition.js +10 -1
- package/dist/src/agents/browser/browserAgentDefinition.js.map +1 -1
- package/dist/src/agents/browser/browserAgentFactory.js +62 -1
- package/dist/src/agents/browser/browserAgentFactory.js.map +1 -1
- package/dist/src/agents/browser/browserAgentFactory.test.js +73 -0
- package/dist/src/agents/browser/browserAgentFactory.test.js.map +1 -1
- package/dist/src/agents/browser/browserAgentInvocation.js +2 -97
- package/dist/src/agents/browser/browserAgentInvocation.js.map +1 -1
- package/dist/src/agents/browser/browserAgentInvocation.test.js +30 -0
- package/dist/src/agents/browser/browserAgentInvocation.test.js.map +1 -1
- package/dist/src/agents/browser/browserManager.js +11 -0
- package/dist/src/agents/browser/browserManager.js.map +1 -1
- package/dist/src/agents/browser/browserManager.test.js +37 -0
- package/dist/src/agents/browser/browserManager.test.js.map +1 -1
- package/dist/src/agents/browser/mcpToolWrapper.d.ts +4 -2
- package/dist/src/agents/browser/mcpToolWrapper.js +30 -8
- package/dist/src/agents/browser/mcpToolWrapper.js.map +1 -1
- package/dist/src/agents/browser/mcpToolWrapper.test.js +30 -0
- package/dist/src/agents/browser/mcpToolWrapper.test.js.map +1 -1
- package/dist/src/agents/browser/mcpToolWrapperConfirmation.test.js +3 -3
- package/dist/src/agents/codebase-investigator.js +3 -3
- package/dist/src/agents/codebase-investigator.js.map +1 -1
- package/dist/src/agents/local-executor.d.ts +3 -1
- package/dist/src/agents/local-executor.js +138 -39
- package/dist/src/agents/local-executor.js.map +1 -1
- package/dist/src/agents/local-executor.test.js +305 -12
- package/dist/src/agents/local-executor.test.js.map +1 -1
- package/dist/src/agents/local-invocation.js +43 -24
- package/dist/src/agents/local-invocation.js.map +1 -1
- package/dist/src/agents/local-invocation.test.js +89 -14
- package/dist/src/agents/local-invocation.test.js.map +1 -1
- package/dist/src/agents/memory-manager-agent.d.ts +25 -0
- package/dist/src/agents/memory-manager-agent.js +137 -0
- package/dist/src/agents/memory-manager-agent.js.map +1 -0
- package/dist/src/agents/memory-manager-agent.test.d.ts +6 -0
- package/dist/src/agents/memory-manager-agent.test.js +117 -0
- package/dist/src/agents/memory-manager-agent.test.js.map +1 -0
- package/dist/src/agents/registry.js +21 -3
- package/dist/src/agents/registry.js.map +1 -1
- package/dist/src/agents/registry.test.js +23 -24
- package/dist/src/agents/registry.test.js.map +1 -1
- package/dist/src/agents/remote-invocation.d.ts +3 -1
- package/dist/src/agents/remote-invocation.js +10 -5
- package/dist/src/agents/remote-invocation.js.map +1 -1
- package/dist/src/agents/remote-invocation.test.js +64 -41
- package/dist/src/agents/remote-invocation.test.js.map +1 -1
- package/dist/src/agents/subagent-tool-wrapper.js +1 -1
- package/dist/src/agents/subagent-tool-wrapper.js.map +1 -1
- package/dist/src/agents/types.d.ts +12 -0
- package/dist/src/agents/types.js +14 -0
- package/dist/src/agents/types.js.map +1 -1
- package/dist/src/availability/policyHelpers.js +41 -1
- package/dist/src/availability/policyHelpers.js.map +1 -1
- package/dist/src/availability/policyHelpers.test.js +47 -0
- package/dist/src/availability/policyHelpers.test.js.map +1 -1
- package/dist/src/code_assist/admin/admin_controls.js +11 -0
- package/dist/src/code_assist/admin/admin_controls.js.map +1 -1
- package/dist/src/code_assist/admin/admin_controls.test.js +68 -0
- package/dist/src/code_assist/admin/admin_controls.test.js.map +1 -1
- package/dist/src/code_assist/admin/mcpUtils.d.ts +16 -1
- package/dist/src/code_assist/admin/mcpUtils.js +43 -0
- package/dist/src/code_assist/admin/mcpUtils.js.map +1 -1
- package/dist/src/code_assist/admin/mcpUtils.test.js +130 -1
- package/dist/src/code_assist/admin/mcpUtils.test.js.map +1 -1
- package/dist/src/code_assist/types.d.ts +458 -0
- package/dist/src/code_assist/types.js +26 -0
- package/dist/src/code_assist/types.js.map +1 -1
- package/dist/src/config/agent-loop-context.d.ts +6 -0
- package/dist/src/config/config.d.ts +41 -10
- package/dist/src/config/config.js +96 -19
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +29 -1
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/defaultModelConfigs.js +265 -9
- package/dist/src/config/defaultModelConfigs.js.map +1 -1
- package/dist/src/config/models.d.ts +13 -2
- package/dist/src/config/models.js +31 -3
- package/dist/src/config/models.js.map +1 -1
- package/dist/src/config/models.test.js +52 -7
- package/dist/src/config/models.test.js.map +1 -1
- package/dist/src/config/path-validation.test.d.ts +6 -0
- package/dist/src/config/path-validation.test.js +59 -0
- package/dist/src/config/path-validation.test.js.map +1 -0
- package/dist/src/core/client.d.ts +1 -0
- package/dist/src/core/client.js +6 -1
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +9 -1
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/contentGenerator.js +36 -6
- package/dist/src/core/contentGenerator.js.map +1 -1
- package/dist/src/core/contentGenerator.test.js +97 -3
- package/dist/src/core/contentGenerator.test.js.map +1 -1
- package/dist/src/core/geminiChat.js +2 -2
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/prompts.test.js +10 -0
- package/dist/src/core/prompts.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/generated/git-commit.js.map +1 -1
- package/dist/src/ide/ide-connection-utils.js +2 -7
- package/dist/src/ide/ide-connection-utils.js.map +1 -1
- package/dist/src/ide/ide-connection-utils.test.js +7 -0
- package/dist/src/ide/ide-connection-utils.test.js.map +1 -1
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/policy/config.js +2 -0
- package/dist/src/policy/config.js.map +1 -1
- package/dist/src/policy/config.test.js +15 -0
- package/dist/src/policy/config.test.js.map +1 -1
- package/dist/src/policy/memory-manager-policy.test.d.ts +6 -0
- package/dist/src/policy/memory-manager-policy.test.js +80 -0
- package/dist/src/policy/memory-manager-policy.test.js.map +1 -0
- package/dist/src/policy/policies/memory-manager.toml +10 -0
- package/dist/src/policy/policies/plan.toml +14 -0
- package/dist/src/policy/policies/yolo.toml +1 -0
- package/dist/src/policy/policy-engine.js +33 -6
- package/dist/src/policy/policy-engine.js.map +1 -1
- package/dist/src/policy/policy-engine.test.js +85 -3
- package/dist/src/policy/policy-engine.test.js.map +1 -1
- package/dist/src/policy/policy-updater.test.js +44 -0
- package/dist/src/policy/policy-updater.test.js.map +1 -1
- package/dist/src/policy/toml-loader.js +2 -0
- package/dist/src/policy/toml-loader.js.map +1 -1
- package/dist/src/policy/types.d.ts +11 -0
- package/dist/src/policy/types.js +5 -0
- package/dist/src/policy/types.js.map +1 -1
- package/dist/src/prompts/promptProvider.js +5 -3
- package/dist/src/prompts/promptProvider.js.map +1 -1
- package/dist/src/prompts/promptProvider.test.js +1 -0
- package/dist/src/prompts/promptProvider.test.js.map +1 -1
- package/dist/src/prompts/snippets-memory-manager.test.d.ts +6 -0
- package/dist/src/prompts/snippets-memory-manager.test.js +31 -0
- package/dist/src/prompts/snippets-memory-manager.test.js.map +1 -0
- package/dist/src/prompts/snippets.d.ts +2 -0
- package/dist/src/prompts/snippets.js +7 -3
- package/dist/src/prompts/snippets.js.map +1 -1
- package/dist/src/prompts/snippets.legacy.d.ts +5 -0
- package/dist/src/prompts/snippets.legacy.js +30 -2
- package/dist/src/prompts/snippets.legacy.js.map +1 -1
- package/dist/src/routing/strategies/classifierStrategy.js +1 -1
- package/dist/src/routing/strategies/classifierStrategy.js.map +1 -1
- package/dist/src/routing/strategies/defaultStrategy.js +1 -1
- package/dist/src/routing/strategies/defaultStrategy.js.map +1 -1
- package/dist/src/routing/strategies/fallbackStrategy.js +1 -1
- package/dist/src/routing/strategies/fallbackStrategy.js.map +1 -1
- package/dist/src/routing/strategies/numericalClassifierStrategy.js +1 -1
- package/dist/src/routing/strategies/numericalClassifierStrategy.js.map +1 -1
- package/dist/src/routing/strategies/overrideStrategy.js +1 -1
- package/dist/src/routing/strategies/overrideStrategy.js.map +1 -1
- package/dist/src/sandbox/macos/MacOsSandboxManager.d.ts +28 -0
- package/dist/src/sandbox/macos/MacOsSandboxManager.integration.test.d.ts +1 -0
- package/dist/src/sandbox/macos/MacOsSandboxManager.integration.test.js +160 -0
- package/dist/src/sandbox/macos/MacOsSandboxManager.integration.test.js.map +1 -0
- package/dist/src/sandbox/macos/MacOsSandboxManager.js +33 -0
- package/dist/src/sandbox/macos/MacOsSandboxManager.js.map +1 -0
- package/dist/src/sandbox/macos/MacOsSandboxManager.test.d.ts +1 -0
- package/dist/src/sandbox/macos/MacOsSandboxManager.test.js +87 -0
- package/dist/src/sandbox/macos/MacOsSandboxManager.test.js.map +1 -0
- package/dist/src/sandbox/macos/baseProfile.d.ts +20 -0
- package/dist/src/sandbox/macos/baseProfile.js +93 -0
- package/dist/src/sandbox/macos/baseProfile.js.map +1 -0
- package/dist/src/sandbox/macos/seatbeltArgsBuilder.d.ts +25 -0
- package/dist/src/sandbox/macos/seatbeltArgsBuilder.js +58 -0
- package/dist/src/sandbox/macos/seatbeltArgsBuilder.js.map +1 -0
- package/dist/src/sandbox/macos/seatbeltArgsBuilder.test.d.ts +1 -0
- package/dist/src/sandbox/macos/seatbeltArgsBuilder.test.js +80 -0
- package/dist/src/sandbox/macos/seatbeltArgsBuilder.test.js.map +1 -0
- package/dist/src/scheduler/scheduler.js +2 -0
- package/dist/src/scheduler/scheduler.js.map +1 -1
- package/dist/src/services/contextManager.js +2 -3
- package/dist/src/services/contextManager.js.map +1 -1
- package/dist/src/services/contextManager.test.js +1 -1
- package/dist/src/services/contextManager.test.js.map +1 -1
- package/dist/src/services/modelConfigService.d.ts +36 -1
- package/dist/src/services/modelConfigService.js +66 -0
- package/dist/src/services/modelConfigService.js.map +1 -1
- package/dist/src/services/sandboxManager.d.ts +3 -4
- package/dist/src/services/sandboxManager.js +1 -14
- package/dist/src/services/sandboxManager.js.map +1 -1
- package/dist/src/services/sandboxManager.test.js +13 -16
- package/dist/src/services/sandboxManager.test.js.map +1 -1
- package/dist/src/services/sandboxManagerFactory.d.ts +11 -0
- package/dist/src/services/sandboxManagerFactory.js +31 -0
- package/dist/src/services/sandboxManagerFactory.js.map +1 -0
- package/dist/src/services/sandboxedFileSystemService.d.ts +17 -0
- package/dist/src/services/sandboxedFileSystemService.js +95 -0
- package/dist/src/services/sandboxedFileSystemService.js.map +1 -0
- package/dist/src/services/sandboxedFileSystemService.test.d.ts +6 -0
- package/dist/src/services/sandboxedFileSystemService.test.js +87 -0
- package/dist/src/services/sandboxedFileSystemService.test.js.map +1 -0
- package/dist/src/services/scripts/GeminiSandbox.cs +370 -0
- package/dist/src/services/shellExecutionService.d.ts +2 -0
- package/dist/src/services/shellExecutionService.js +79 -75
- package/dist/src/services/shellExecutionService.js.map +1 -1
- package/dist/src/services/trackerTypes.d.ts +1 -0
- package/dist/src/services/trackerTypes.js +1 -0
- package/dist/src/services/trackerTypes.js.map +1 -1
- package/dist/src/services/windowsSandboxManager.d.ts +27 -0
- package/dist/src/services/windowsSandboxManager.js +148 -0
- package/dist/src/services/windowsSandboxManager.js.map +1 -0
- package/dist/src/services/windowsSandboxManager.test.d.ts +6 -0
- package/dist/src/services/windowsSandboxManager.test.js +59 -0
- package/dist/src/services/windowsSandboxManager.test.js.map +1 -0
- package/dist/src/services/worktreeService.d.ts +33 -0
- package/dist/src/services/worktreeService.js +174 -0
- package/dist/src/services/worktreeService.js.map +1 -0
- package/dist/src/services/worktreeService.test.d.ts +6 -0
- package/dist/src/services/worktreeService.test.js +200 -0
- package/dist/src/services/worktreeService.test.js.map +1 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +4 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +1 -0
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +2 -0
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
- package/dist/src/telemetry/loggers.test.js +62 -40
- package/dist/src/telemetry/loggers.test.js.map +1 -1
- package/dist/src/telemetry/types.d.ts +1 -0
- package/dist/src/telemetry/types.js +3 -0
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/tools/definitions/model-family-sets/default-legacy.js +8 -1
- package/dist/src/tools/definitions/model-family-sets/default-legacy.js.map +1 -1
- package/dist/src/tools/definitions/model-family-sets/gemini-3.js +8 -1
- package/dist/src/tools/definitions/model-family-sets/gemini-3.js.map +1 -1
- package/dist/src/tools/exit-plan-mode.d.ts +6 -1
- package/dist/src/tools/exit-plan-mode.js +17 -6
- package/dist/src/tools/exit-plan-mode.js.map +1 -1
- package/dist/src/tools/exit-plan-mode.test.js +22 -1
- package/dist/src/tools/exit-plan-mode.test.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.d.ts +22 -3
- package/dist/src/tools/mcp-client-manager.js +84 -32
- package/dist/src/tools/mcp-client-manager.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.test.js +76 -56
- package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
- package/dist/src/tools/mcp-client.d.ts +15 -6
- package/dist/src/tools/mcp-client.js +85 -71
- package/dist/src/tools/mcp-client.js.map +1 -1
- package/dist/src/tools/mcp-client.test.js +195 -88
- package/dist/src/tools/mcp-client.test.js.map +1 -1
- package/dist/src/tools/tool-registry.d.ts +2 -1
- package/dist/src/tools/tool-registry.js +12 -1
- package/dist/src/tools/tool-registry.js.map +1 -1
- package/dist/src/tools/tool-registry.test.js +15 -0
- package/dist/src/tools/tool-registry.test.js.map +1 -1
- package/dist/src/tools/tools.d.ts +1 -1
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/trackerTools.js +6 -1
- package/dist/src/tools/trackerTools.js.map +1 -1
- package/dist/src/tools/trackerTools.test.js +9 -1
- package/dist/src/tools/trackerTools.test.js.map +1 -1
- package/dist/src/tools/write-todos.js +1 -0
- package/dist/src/tools/write-todos.js.map +1 -1
- package/dist/src/tools/write-todos.test.js +4 -1
- package/dist/src/tools/write-todos.test.js.map +1 -1
- package/dist/src/utils/agent-sanitization-utils.d.ts +23 -0
- package/dist/src/utils/agent-sanitization-utils.js +123 -0
- package/dist/src/utils/agent-sanitization-utils.js.map +1 -0
- package/dist/src/utils/agent-sanitization-utils.test.d.ts +6 -0
- package/dist/src/utils/agent-sanitization-utils.test.js +83 -0
- package/dist/src/utils/agent-sanitization-utils.test.js.map +1 -0
- package/dist/src/utils/browserConsent.d.ts +17 -0
- package/dist/src/utils/browserConsent.js +78 -0
- package/dist/src/utils/browserConsent.js.map +1 -0
- package/dist/src/utils/browserConsent.test.d.ts +6 -0
- package/dist/src/utils/browserConsent.test.js +93 -0
- package/dist/src/utils/browserConsent.test.js.map +1 -0
- package/dist/src/utils/compatibility.d.ts +16 -0
- package/dist/src/utils/compatibility.js +58 -9
- package/dist/src/utils/compatibility.js.map +1 -1
- package/dist/src/utils/compatibility.test.js +127 -29
- package/dist/src/utils/compatibility.test.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.d.ts +2 -2
- package/dist/src/utils/memoryDiscovery.js +5 -10
- package/dist/src/utils/memoryDiscovery.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.test.js +37 -37
- package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
- package/dist/src/utils/memoryImportProcessor.js +5 -5
- package/dist/src/utils/memoryImportProcessor.js.map +1 -1
- package/dist/src/utils/surface.js +4 -3
- package/dist/src/utils/surface.js.map +1 -1
- package/dist/src/utils/toolCallContext.d.ts +2 -0
- package/dist/src/utils/toolCallContext.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overrideStrategy.js","sourceRoot":"","sources":["../../../../src/routing/strategies/overrideStrategy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AASnE;;GAEG;AACH,MAAM,OAAO,gBAAgB;IAClB,IAAI,GAAG,UAAU,CAAC;IAE3B,KAAK,CAAC,KAAK,CACT,OAAuB,EACvB,MAAc,EACd,cAA6B,EAC7B,oBAAyC;QAEzC,MAAM,aAAa,GAAG,OAAO,CAAC,cAAc,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QAElE,8DAA8D;QAC9D,IAAI,WAAW,CAAC,aAAa,EAAE,MAAM,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,oCAAoC;QACpC,OAAO;YACL,KAAK,EAAE,YAAY,CACjB,aAAa,EACb,MAAM,CAAC,uBAAuB,EAAE,EAAE,IAAI,KAAK,
|
|
1
|
+
{"version":3,"file":"overrideStrategy.js","sourceRoot":"","sources":["../../../../src/routing/strategies/overrideStrategy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AASnE;;GAEG;AACH,MAAM,OAAO,gBAAgB;IAClB,IAAI,GAAG,UAAU,CAAC;IAE3B,KAAK,CAAC,KAAK,CACT,OAAuB,EACvB,MAAc,EACd,cAA6B,EAC7B,oBAAyC;QAEzC,MAAM,aAAa,GAAG,OAAO,CAAC,cAAc,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QAElE,8DAA8D;QAC9D,IAAI,WAAW,CAAC,aAAa,EAAE,MAAM,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,oCAAoC;QACpC,OAAO;YACL,KAAK,EAAE,YAAY,CACjB,aAAa,EACb,MAAM,CAAC,uBAAuB,EAAE,EAAE,IAAI,KAAK,EAC3C,KAAK,EACL,MAAM,CAAC,0BAA0B,EAAE,EAAE,IAAI,IAAI,EAC7C,MAAM,CACP;YACD,QAAQ,EAAE;gBACR,MAAM,EAAE,IAAI,CAAC,IAAI;gBACjB,SAAS,EAAE,CAAC;gBACZ,SAAS,EAAE,sDAAsD,aAAa,EAAE;aACjF;SACF,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { type SandboxManager, type SandboxRequest, type SandboxedCommand } from '../../services/sandboxManager.js';
|
|
7
|
+
import { type EnvironmentSanitizationConfig } from '../../services/environmentSanitization.js';
|
|
8
|
+
/**
|
|
9
|
+
* Options for configuring the MacOsSandboxManager.
|
|
10
|
+
*/
|
|
11
|
+
export interface MacOsSandboxOptions {
|
|
12
|
+
/** The primary workspace path to allow access to within the sandbox. */
|
|
13
|
+
workspace: string;
|
|
14
|
+
/** Additional paths to allow access to within the sandbox. */
|
|
15
|
+
allowedPaths?: string[];
|
|
16
|
+
/** Whether network access is allowed. */
|
|
17
|
+
networkAccess?: boolean;
|
|
18
|
+
/** Optional base sanitization config. */
|
|
19
|
+
sanitizationConfig?: EnvironmentSanitizationConfig;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A SandboxManager implementation for macOS that uses Seatbelt.
|
|
23
|
+
*/
|
|
24
|
+
export declare class MacOsSandboxManager implements SandboxManager {
|
|
25
|
+
private readonly options;
|
|
26
|
+
constructor(options: MacOsSandboxOptions);
|
|
27
|
+
prepareCommand(req: SandboxRequest): Promise<SandboxedCommand>;
|
|
28
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
7
|
+
import { MacOsSandboxManager } from './MacOsSandboxManager.js';
|
|
8
|
+
import { ShellExecutionService } from '../../services/shellExecutionService.js';
|
|
9
|
+
import { getSecureSanitizationConfig } from '../../services/environmentSanitization.js';
|
|
10
|
+
import {} from '../../services/sandboxManager.js';
|
|
11
|
+
import { execFile } from 'node:child_process';
|
|
12
|
+
import { promisify } from 'node:util';
|
|
13
|
+
import os from 'node:os';
|
|
14
|
+
import fs from 'node:fs';
|
|
15
|
+
import path from 'node:path';
|
|
16
|
+
import http from 'node:http';
|
|
17
|
+
/**
|
|
18
|
+
* A simple asynchronous wrapper for execFile that returns the exit status,
|
|
19
|
+
* stdout, and stderr. Unlike spawnSync, this does not block the Node.js
|
|
20
|
+
* event loop, allowing the local HTTP test server to function.
|
|
21
|
+
*/
|
|
22
|
+
async function runCommand(command) {
|
|
23
|
+
try {
|
|
24
|
+
const { stdout, stderr } = await promisify(execFile)(command.program, command.args, {
|
|
25
|
+
cwd: command.cwd,
|
|
26
|
+
env: command.env,
|
|
27
|
+
encoding: 'utf-8',
|
|
28
|
+
});
|
|
29
|
+
return { status: 0, stdout, stderr };
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
const err = error;
|
|
33
|
+
return {
|
|
34
|
+
status: err.code ?? 1,
|
|
35
|
+
stdout: err.stdout ?? '',
|
|
36
|
+
stderr: err.stderr ?? '',
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
describe.skipIf(os.platform() !== 'darwin')('MacOsSandboxManager Integration', () => {
|
|
41
|
+
describe('Basic Execution', () => {
|
|
42
|
+
it('should execute commands within the workspace', async () => {
|
|
43
|
+
const manager = new MacOsSandboxManager({ workspace: process.cwd() });
|
|
44
|
+
const command = await manager.prepareCommand({
|
|
45
|
+
command: 'echo',
|
|
46
|
+
args: ['sandbox test'],
|
|
47
|
+
cwd: process.cwd(),
|
|
48
|
+
env: process.env,
|
|
49
|
+
});
|
|
50
|
+
const execResult = await runCommand(command);
|
|
51
|
+
expect(execResult.status).toBe(0);
|
|
52
|
+
expect(execResult.stdout.trim()).toBe('sandbox test');
|
|
53
|
+
});
|
|
54
|
+
it('should support interactive pseudo-terminals (node-pty)', async () => {
|
|
55
|
+
const manager = new MacOsSandboxManager({ workspace: process.cwd() });
|
|
56
|
+
const abortController = new AbortController();
|
|
57
|
+
// Verify that node-pty file descriptors are successfully allocated inside the sandbox
|
|
58
|
+
// by using the bash [ -t 1 ] idiom to check if stdout is a TTY.
|
|
59
|
+
const handle = await ShellExecutionService.execute('bash -c "if [ -t 1 ]; then echo True; else echo False; fi"', process.cwd(), () => { }, abortController.signal, true, {
|
|
60
|
+
sanitizationConfig: getSecureSanitizationConfig(),
|
|
61
|
+
sandboxManager: manager,
|
|
62
|
+
});
|
|
63
|
+
const result = await handle.result;
|
|
64
|
+
expect(result.error).toBeNull();
|
|
65
|
+
expect(result.exitCode).toBe(0);
|
|
66
|
+
expect(result.output).toContain('True');
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
describe('File System Access', () => {
|
|
70
|
+
it('should block file system access outside the workspace', async () => {
|
|
71
|
+
const manager = new MacOsSandboxManager({ workspace: process.cwd() });
|
|
72
|
+
const blockedPath = '/Users/Shared/.gemini_test_sandbox_blocked';
|
|
73
|
+
const command = await manager.prepareCommand({
|
|
74
|
+
command: 'touch',
|
|
75
|
+
args: [blockedPath],
|
|
76
|
+
cwd: process.cwd(),
|
|
77
|
+
env: process.env,
|
|
78
|
+
});
|
|
79
|
+
const execResult = await runCommand(command);
|
|
80
|
+
expect(execResult.status).not.toBe(0);
|
|
81
|
+
expect(execResult.stderr).toContain('Operation not permitted');
|
|
82
|
+
});
|
|
83
|
+
it('should grant file system access to explicitly allowed paths', async () => {
|
|
84
|
+
// Create a unique temporary directory to prevent artifacts and test flakiness
|
|
85
|
+
const allowedDir = fs.mkdtempSync(path.join(os.tmpdir(), 'gemini-sandbox-test-'));
|
|
86
|
+
try {
|
|
87
|
+
const manager = new MacOsSandboxManager({
|
|
88
|
+
workspace: process.cwd(),
|
|
89
|
+
allowedPaths: [allowedDir],
|
|
90
|
+
});
|
|
91
|
+
const testFile = path.join(allowedDir, 'test.txt');
|
|
92
|
+
const command = await manager.prepareCommand({
|
|
93
|
+
command: 'touch',
|
|
94
|
+
args: [testFile],
|
|
95
|
+
cwd: process.cwd(),
|
|
96
|
+
env: process.env,
|
|
97
|
+
});
|
|
98
|
+
const execResult = await runCommand(command);
|
|
99
|
+
expect(execResult.status).toBe(0);
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
fs.rmSync(allowedDir, { recursive: true, force: true });
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
describe('Network Access', () => {
|
|
107
|
+
let testServer;
|
|
108
|
+
let testServerUrl;
|
|
109
|
+
beforeAll(async () => {
|
|
110
|
+
testServer = http.createServer((_, res) => {
|
|
111
|
+
// Ensure connections are closed immediately to prevent hanging
|
|
112
|
+
res.setHeader('Connection', 'close');
|
|
113
|
+
res.writeHead(200);
|
|
114
|
+
res.end('ok');
|
|
115
|
+
});
|
|
116
|
+
await new Promise((resolve, reject) => {
|
|
117
|
+
testServer.on('error', reject);
|
|
118
|
+
testServer.listen(0, '127.0.0.1', () => {
|
|
119
|
+
const address = testServer.address();
|
|
120
|
+
testServerUrl = `http://127.0.0.1:${address.port}`;
|
|
121
|
+
resolve();
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
afterAll(async () => {
|
|
126
|
+
if (testServer) {
|
|
127
|
+
await new Promise((resolve) => {
|
|
128
|
+
testServer.close(() => resolve());
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
it('should block network access by default', async () => {
|
|
133
|
+
const manager = new MacOsSandboxManager({ workspace: process.cwd() });
|
|
134
|
+
const command = await manager.prepareCommand({
|
|
135
|
+
command: 'curl',
|
|
136
|
+
args: ['-s', '--connect-timeout', '1', testServerUrl],
|
|
137
|
+
cwd: process.cwd(),
|
|
138
|
+
env: process.env,
|
|
139
|
+
});
|
|
140
|
+
const execResult = await runCommand(command);
|
|
141
|
+
expect(execResult.status).not.toBe(0);
|
|
142
|
+
});
|
|
143
|
+
it('should grant network access when explicitly allowed', async () => {
|
|
144
|
+
const manager = new MacOsSandboxManager({
|
|
145
|
+
workspace: process.cwd(),
|
|
146
|
+
networkAccess: true,
|
|
147
|
+
});
|
|
148
|
+
const command = await manager.prepareCommand({
|
|
149
|
+
command: 'curl',
|
|
150
|
+
args: ['-s', '--connect-timeout', '1', testServerUrl],
|
|
151
|
+
cwd: process.cwd(),
|
|
152
|
+
env: process.env,
|
|
153
|
+
});
|
|
154
|
+
const execResult = await runCommand(command);
|
|
155
|
+
expect(execResult.status).toBe(0);
|
|
156
|
+
expect(execResult.stdout.trim()).toBe('ok');
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
//# sourceMappingURL=MacOsSandboxManager.integration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MacOsSandboxManager.integration.test.js","sourceRoot":"","sources":["../../../../src/sandbox/macos/MacOsSandboxManager.integration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import {} from '../../services/sandboxManager.js';
|
|
7
|
+
import { sanitizeEnvironment, getSecureSanitizationConfig, } from '../../services/environmentSanitization.js';
|
|
8
|
+
import { buildSeatbeltArgs } from './seatbeltArgsBuilder.js';
|
|
9
|
+
/**
|
|
10
|
+
* A SandboxManager implementation for macOS that uses Seatbelt.
|
|
11
|
+
*/
|
|
12
|
+
export class MacOsSandboxManager {
|
|
13
|
+
options;
|
|
14
|
+
constructor(options) {
|
|
15
|
+
this.options = options;
|
|
16
|
+
}
|
|
17
|
+
async prepareCommand(req) {
|
|
18
|
+
const sanitizationConfig = getSecureSanitizationConfig(req.config?.sanitizationConfig, this.options.sanitizationConfig);
|
|
19
|
+
const sanitizedEnv = sanitizeEnvironment(req.env, sanitizationConfig);
|
|
20
|
+
const sandboxArgs = buildSeatbeltArgs({
|
|
21
|
+
workspace: this.options.workspace,
|
|
22
|
+
allowedPaths: this.options.allowedPaths,
|
|
23
|
+
networkAccess: this.options.networkAccess,
|
|
24
|
+
});
|
|
25
|
+
return {
|
|
26
|
+
program: '/usr/bin/sandbox-exec',
|
|
27
|
+
args: [...sandboxArgs, '--', req.command, ...req.args],
|
|
28
|
+
env: sanitizedEnv,
|
|
29
|
+
cwd: req.cwd,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=MacOsSandboxManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MacOsSandboxManager.js","sourceRoot":"","sources":["../../../../src/sandbox/macos/MacOsSandboxManager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAIN,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,mBAAmB,EACnB,2BAA2B,GAE5B,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAgB7D;;GAEG;AACH,MAAM,OAAO,mBAAmB;IACD;IAA7B,YAA6B,OAA4B;QAA5B,YAAO,GAAP,OAAO,CAAqB;IAAG,CAAC;IAE7D,KAAK,CAAC,cAAc,CAAC,GAAmB;QACtC,MAAM,kBAAkB,GAAG,2BAA2B,CACpD,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAC9B,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAChC,CAAC;QAEF,MAAM,YAAY,GAAG,mBAAmB,CAAC,GAAG,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;QAEtE,MAAM,WAAW,GAAG,iBAAiB,CAAC;YACpC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YACjC,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY;YACvC,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa;SAC1C,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE,uBAAuB;YAChC,IAAI,EAAE,CAAC,GAAG,WAAW,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;YACtD,GAAG,EAAE,YAAY;YACjB,GAAG,EAAE,GAAG,CAAC,GAAG;SACb,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, vi, beforeEach, afterEach, } from 'vitest';
|
|
7
|
+
import { MacOsSandboxManager } from './MacOsSandboxManager.js';
|
|
8
|
+
import * as seatbeltArgsBuilder from './seatbeltArgsBuilder.js';
|
|
9
|
+
describe('MacOsSandboxManager', () => {
|
|
10
|
+
const mockWorkspace = '/test/workspace';
|
|
11
|
+
const mockAllowedPaths = ['/test/allowed'];
|
|
12
|
+
const mockNetworkAccess = true;
|
|
13
|
+
let manager;
|
|
14
|
+
let buildArgsSpy;
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
manager = new MacOsSandboxManager({
|
|
17
|
+
workspace: mockWorkspace,
|
|
18
|
+
allowedPaths: mockAllowedPaths,
|
|
19
|
+
networkAccess: mockNetworkAccess,
|
|
20
|
+
});
|
|
21
|
+
buildArgsSpy = vi
|
|
22
|
+
.spyOn(seatbeltArgsBuilder, 'buildSeatbeltArgs')
|
|
23
|
+
.mockReturnValue([
|
|
24
|
+
'-p',
|
|
25
|
+
'(mock profile)',
|
|
26
|
+
'-D',
|
|
27
|
+
'WORKSPACE=/test/workspace',
|
|
28
|
+
]);
|
|
29
|
+
});
|
|
30
|
+
afterEach(() => {
|
|
31
|
+
vi.restoreAllMocks();
|
|
32
|
+
});
|
|
33
|
+
it('should correctly invoke buildSeatbeltArgs with the configured options', async () => {
|
|
34
|
+
await manager.prepareCommand({
|
|
35
|
+
command: 'echo',
|
|
36
|
+
args: ['hello'],
|
|
37
|
+
cwd: mockWorkspace,
|
|
38
|
+
env: {},
|
|
39
|
+
});
|
|
40
|
+
expect(buildArgsSpy).toHaveBeenCalledWith({
|
|
41
|
+
workspace: mockWorkspace,
|
|
42
|
+
allowedPaths: mockAllowedPaths,
|
|
43
|
+
networkAccess: mockNetworkAccess,
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
it('should format the executable and arguments correctly for sandbox-exec', async () => {
|
|
47
|
+
const result = await manager.prepareCommand({
|
|
48
|
+
command: 'echo',
|
|
49
|
+
args: ['hello'],
|
|
50
|
+
cwd: mockWorkspace,
|
|
51
|
+
env: {},
|
|
52
|
+
});
|
|
53
|
+
expect(result.program).toBe('/usr/bin/sandbox-exec');
|
|
54
|
+
expect(result.args).toEqual([
|
|
55
|
+
'-p',
|
|
56
|
+
'(mock profile)',
|
|
57
|
+
'-D',
|
|
58
|
+
'WORKSPACE=/test/workspace',
|
|
59
|
+
'--',
|
|
60
|
+
'echo',
|
|
61
|
+
'hello',
|
|
62
|
+
]);
|
|
63
|
+
});
|
|
64
|
+
it('should correctly pass through the cwd to the resulting command', async () => {
|
|
65
|
+
const result = await manager.prepareCommand({
|
|
66
|
+
command: 'echo',
|
|
67
|
+
args: ['hello'],
|
|
68
|
+
cwd: '/test/different/cwd',
|
|
69
|
+
env: {},
|
|
70
|
+
});
|
|
71
|
+
expect(result.cwd).toBe('/test/different/cwd');
|
|
72
|
+
});
|
|
73
|
+
it('should apply environment sanitization via the default mechanisms', async () => {
|
|
74
|
+
const result = await manager.prepareCommand({
|
|
75
|
+
command: 'echo',
|
|
76
|
+
args: ['hello'],
|
|
77
|
+
cwd: mockWorkspace,
|
|
78
|
+
env: {
|
|
79
|
+
SAFE_VAR: '1',
|
|
80
|
+
GITHUB_TOKEN: 'sensitive',
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
expect(result.env['SAFE_VAR']).toBe('1');
|
|
84
|
+
expect(result.env['GITHUB_TOKEN']).toBeUndefined();
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=MacOsSandboxManager.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MacOsSandboxManager.test.js","sourceRoot":"","sources":["../../../../src/sandbox/macos/MacOsSandboxManager.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,QAAQ,EACR,EAAE,EACF,MAAM,EACN,EAAE,EACF,UAAU,EACV,SAAS,GAEV,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,mBAAmB,MAAM,0BAA0B,CAAC;AAEhE,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,MAAM,aAAa,GAAG,iBAAiB,CAAC;IACxC,MAAM,gBAAgB,GAAG,CAAC,eAAe,CAAC,CAAC;IAC3C,MAAM,iBAAiB,GAAG,IAAI,CAAC;IAE/B,IAAI,OAA4B,CAAC;IACjC,IAAI,YAAwE,CAAC;IAE7E,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,GAAG,IAAI,mBAAmB,CAAC;YAChC,SAAS,EAAE,aAAa;YACxB,YAAY,EAAE,gBAAgB;YAC9B,aAAa,EAAE,iBAAiB;SACjC,CAAC,CAAC;QAEH,YAAY,GAAG,EAAE;aACd,KAAK,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;aAC/C,eAAe,CAAC;YACf,IAAI;YACJ,gBAAgB;YAChB,IAAI;YACJ,2BAA2B;SAC5B,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,OAAO,CAAC,cAAc,CAAC;YAC3B,OAAO,EAAE,MAAM;YACf,IAAI,EAAE,CAAC,OAAO,CAAC;YACf,GAAG,EAAE,aAAa;YAClB,GAAG,EAAE,EAAE;SACR,CAAC,CAAC;QAEH,MAAM,CAAC,YAAY,CAAC,CAAC,oBAAoB,CAAC;YACxC,SAAS,EAAE,aAAa;YACxB,YAAY,EAAE,gBAAgB;YAC9B,aAAa,EAAE,iBAAiB;SACjC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC;YAC1C,OAAO,EAAE,MAAM;YACf,IAAI,EAAE,CAAC,OAAO,CAAC;YACf,GAAG,EAAE,aAAa;YAClB,GAAG,EAAE,EAAE;SACR,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;YAC1B,IAAI;YACJ,gBAAgB;YAChB,IAAI;YACJ,2BAA2B;YAC3B,IAAI;YACJ,MAAM;YACN,OAAO;SACR,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;QAC9E,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC;YAC1C,OAAO,EAAE,MAAM;YACf,IAAI,EAAE,CAAC,OAAO,CAAC;YACf,GAAG,EAAE,qBAAqB;YAC1B,GAAG,EAAE,EAAE;SACR,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAChF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC;YAC1C,OAAO,EAAE,MAAM;YACf,IAAI,EAAE,CAAC,OAAO,CAAC;YACf,GAAG,EAAE,aAAa;YAClB,GAAG,EAAE;gBACH,QAAQ,EAAE,GAAG;gBACb,YAAY,EAAE,WAAW;aAC1B;SACF,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* The base macOS Seatbelt (SBPL) profile for tool execution.
|
|
8
|
+
*
|
|
9
|
+
* This uses a strict allowlist (deny default) but imports Apple's base system profile
|
|
10
|
+
* to handle undocumented internal dependencies, sysctls, and IPC mach ports required
|
|
11
|
+
* by standard tools to avoid "Abort trap: 6".
|
|
12
|
+
*/
|
|
13
|
+
export declare const BASE_SEATBELT_PROFILE = "(version 1)\n(deny default)\n\n(import \"system.sb\")\n\n; Core execution requirements\n(allow process-exec)\n(allow process-fork)\n(allow signal (target same-sandbox))\n(allow process-info* (target same-sandbox))\n\n; Allow basic read access to system frameworks and libraries required to run\n(allow file-read*\n (subpath \"/System\")\n (subpath \"/usr/lib\")\n (subpath \"/usr/share\")\n (subpath \"/usr/bin\")\n (subpath \"/bin\")\n (subpath \"/sbin\")\n (subpath \"/usr/local/bin\")\n (subpath \"/opt/homebrew\")\n (subpath \"/Library\")\n (subpath \"/private/var/run\")\n (subpath \"/private/var/db\")\n (subpath \"/private/etc\")\n)\n\n; PTY and Terminal support\n(allow pseudo-tty)\n(allow file-read* file-write* file-ioctl (literal \"/dev/ptmx\"))\n(allow file-read* file-write* file-ioctl (regex #\"^/dev/ttys[0-9]+\"))\n\n; Allow read/write access to temporary directories and common device nodes\n(allow file-read* file-write*\n (literal \"/dev/null\")\n (literal \"/dev/zero\")\n (subpath \"/tmp\")\n (subpath \"/private/tmp\")\n (subpath (param \"TMPDIR\"))\n)\n\n; Workspace access using parameterized paths\n(allow file-read* file-write*\n (subpath (param \"WORKSPACE\"))\n)\n";
|
|
14
|
+
/**
|
|
15
|
+
* The network-specific macOS Seatbelt (SBPL) profile rules.
|
|
16
|
+
*
|
|
17
|
+
* These rules are appended to the base profile when network access is enabled,
|
|
18
|
+
* allowing standard socket creation, DNS resolution, and TLS certificate validation.
|
|
19
|
+
*/
|
|
20
|
+
export declare const NETWORK_SEATBELT_PROFILE = "\n; Network Access\n(allow network*)\n\n(allow system-socket\n (require-all\n (socket-domain AF_SYSTEM)\n (socket-protocol 2)\n )\n)\n\n(allow mach-lookup\n (global-name \"com.apple.bsd.dirhelper\")\n (global-name \"com.apple.system.opendirectoryd.membership\")\n (global-name \"com.apple.SecurityServer\")\n (global-name \"com.apple.networkd\")\n (global-name \"com.apple.ocspd\")\n (global-name \"com.apple.trustd.agent\")\n (global-name \"com.apple.mDNSResponder\")\n (global-name \"com.apple.mDNSResponderHelper\")\n (global-name \"com.apple.SystemConfiguration.DNSConfiguration\")\n (global-name \"com.apple.SystemConfiguration.configd\")\n)\n\n(allow sysctl-read\n (sysctl-name-regex #\"^net.routetable\")\n)\n";
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* The base macOS Seatbelt (SBPL) profile for tool execution.
|
|
8
|
+
*
|
|
9
|
+
* This uses a strict allowlist (deny default) but imports Apple's base system profile
|
|
10
|
+
* to handle undocumented internal dependencies, sysctls, and IPC mach ports required
|
|
11
|
+
* by standard tools to avoid "Abort trap: 6".
|
|
12
|
+
*/
|
|
13
|
+
export const BASE_SEATBELT_PROFILE = `(version 1)
|
|
14
|
+
(deny default)
|
|
15
|
+
|
|
16
|
+
(import "system.sb")
|
|
17
|
+
|
|
18
|
+
; Core execution requirements
|
|
19
|
+
(allow process-exec)
|
|
20
|
+
(allow process-fork)
|
|
21
|
+
(allow signal (target same-sandbox))
|
|
22
|
+
(allow process-info* (target same-sandbox))
|
|
23
|
+
|
|
24
|
+
; Allow basic read access to system frameworks and libraries required to run
|
|
25
|
+
(allow file-read*
|
|
26
|
+
(subpath "/System")
|
|
27
|
+
(subpath "/usr/lib")
|
|
28
|
+
(subpath "/usr/share")
|
|
29
|
+
(subpath "/usr/bin")
|
|
30
|
+
(subpath "/bin")
|
|
31
|
+
(subpath "/sbin")
|
|
32
|
+
(subpath "/usr/local/bin")
|
|
33
|
+
(subpath "/opt/homebrew")
|
|
34
|
+
(subpath "/Library")
|
|
35
|
+
(subpath "/private/var/run")
|
|
36
|
+
(subpath "/private/var/db")
|
|
37
|
+
(subpath "/private/etc")
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
; PTY and Terminal support
|
|
41
|
+
(allow pseudo-tty)
|
|
42
|
+
(allow file-read* file-write* file-ioctl (literal "/dev/ptmx"))
|
|
43
|
+
(allow file-read* file-write* file-ioctl (regex #"^/dev/ttys[0-9]+"))
|
|
44
|
+
|
|
45
|
+
; Allow read/write access to temporary directories and common device nodes
|
|
46
|
+
(allow file-read* file-write*
|
|
47
|
+
(literal "/dev/null")
|
|
48
|
+
(literal "/dev/zero")
|
|
49
|
+
(subpath "/tmp")
|
|
50
|
+
(subpath "/private/tmp")
|
|
51
|
+
(subpath (param "TMPDIR"))
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
; Workspace access using parameterized paths
|
|
55
|
+
(allow file-read* file-write*
|
|
56
|
+
(subpath (param "WORKSPACE"))
|
|
57
|
+
)
|
|
58
|
+
`;
|
|
59
|
+
/**
|
|
60
|
+
* The network-specific macOS Seatbelt (SBPL) profile rules.
|
|
61
|
+
*
|
|
62
|
+
* These rules are appended to the base profile when network access is enabled,
|
|
63
|
+
* allowing standard socket creation, DNS resolution, and TLS certificate validation.
|
|
64
|
+
*/
|
|
65
|
+
export const NETWORK_SEATBELT_PROFILE = `
|
|
66
|
+
; Network Access
|
|
67
|
+
(allow network*)
|
|
68
|
+
|
|
69
|
+
(allow system-socket
|
|
70
|
+
(require-all
|
|
71
|
+
(socket-domain AF_SYSTEM)
|
|
72
|
+
(socket-protocol 2)
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
(allow mach-lookup
|
|
77
|
+
(global-name "com.apple.bsd.dirhelper")
|
|
78
|
+
(global-name "com.apple.system.opendirectoryd.membership")
|
|
79
|
+
(global-name "com.apple.SecurityServer")
|
|
80
|
+
(global-name "com.apple.networkd")
|
|
81
|
+
(global-name "com.apple.ocspd")
|
|
82
|
+
(global-name "com.apple.trustd.agent")
|
|
83
|
+
(global-name "com.apple.mDNSResponder")
|
|
84
|
+
(global-name "com.apple.mDNSResponderHelper")
|
|
85
|
+
(global-name "com.apple.SystemConfiguration.DNSConfiguration")
|
|
86
|
+
(global-name "com.apple.SystemConfiguration.configd")
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
(allow sysctl-read
|
|
90
|
+
(sysctl-name-regex #"^net.routetable")
|
|
91
|
+
)
|
|
92
|
+
`;
|
|
93
|
+
//# sourceMappingURL=baseProfile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseProfile.js","sourceRoot":"","sources":["../../../../src/sandbox/macos/baseProfile.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6CpC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BvC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Options for building macOS Seatbelt arguments.
|
|
8
|
+
*/
|
|
9
|
+
export interface SeatbeltArgsOptions {
|
|
10
|
+
/** The primary workspace path to allow access to. */
|
|
11
|
+
workspace: string;
|
|
12
|
+
/** Additional paths to allow access to. */
|
|
13
|
+
allowedPaths?: string[];
|
|
14
|
+
/** Whether to allow network access. */
|
|
15
|
+
networkAccess?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Builds the arguments array for sandbox-exec using a strict allowlist profile.
|
|
19
|
+
* It relies on parameters passed to sandbox-exec via the -D flag to avoid
|
|
20
|
+
* string interpolation vulnerabilities, and normalizes paths against symlink escapes.
|
|
21
|
+
*
|
|
22
|
+
* Returns arguments up to the end of sandbox-exec configuration (e.g. ['-p', '<profile>', '-D', ...])
|
|
23
|
+
* Does not include the final '--' separator or the command to run.
|
|
24
|
+
*/
|
|
25
|
+
export declare function buildSeatbeltArgs(options: SeatbeltArgsOptions): string[];
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import fs from 'node:fs';
|
|
7
|
+
import os from 'node:os';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import { BASE_SEATBELT_PROFILE, NETWORK_SEATBELT_PROFILE, } from './baseProfile.js';
|
|
10
|
+
/**
|
|
11
|
+
* Resolves symlinks for a given path to prevent sandbox escapes.
|
|
12
|
+
* If a file does not exist (ENOENT), it recursively resolves the parent directory.
|
|
13
|
+
* Other errors (e.g. EACCES) are re-thrown.
|
|
14
|
+
*/
|
|
15
|
+
function tryRealpath(p) {
|
|
16
|
+
try {
|
|
17
|
+
return fs.realpathSync(p);
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
if (e instanceof Error && 'code' in e && e.code === 'ENOENT') {
|
|
21
|
+
const parentDir = path.dirname(p);
|
|
22
|
+
if (parentDir === p) {
|
|
23
|
+
return p;
|
|
24
|
+
}
|
|
25
|
+
return path.join(tryRealpath(parentDir), path.basename(p));
|
|
26
|
+
}
|
|
27
|
+
throw e;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Builds the arguments array for sandbox-exec using a strict allowlist profile.
|
|
32
|
+
* It relies on parameters passed to sandbox-exec via the -D flag to avoid
|
|
33
|
+
* string interpolation vulnerabilities, and normalizes paths against symlink escapes.
|
|
34
|
+
*
|
|
35
|
+
* Returns arguments up to the end of sandbox-exec configuration (e.g. ['-p', '<profile>', '-D', ...])
|
|
36
|
+
* Does not include the final '--' separator or the command to run.
|
|
37
|
+
*/
|
|
38
|
+
export function buildSeatbeltArgs(options) {
|
|
39
|
+
let profile = BASE_SEATBELT_PROFILE + '\n';
|
|
40
|
+
const args = [];
|
|
41
|
+
const workspacePath = tryRealpath(options.workspace);
|
|
42
|
+
args.push('-D', `WORKSPACE=${workspacePath}`);
|
|
43
|
+
const tmpPath = tryRealpath(os.tmpdir());
|
|
44
|
+
args.push('-D', `TMPDIR=${tmpPath}`);
|
|
45
|
+
if (options.allowedPaths) {
|
|
46
|
+
for (let i = 0; i < options.allowedPaths.length; i++) {
|
|
47
|
+
const allowedPath = tryRealpath(options.allowedPaths[i]);
|
|
48
|
+
args.push('-D', `ALLOWED_PATH_${i}=${allowedPath}`);
|
|
49
|
+
profile += `(allow file-read* file-write* (subpath (param "ALLOWED_PATH_${i}")))\n`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (options.networkAccess) {
|
|
53
|
+
profile += NETWORK_SEATBELT_PROFILE;
|
|
54
|
+
}
|
|
55
|
+
args.unshift('-p', profile);
|
|
56
|
+
return args;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=seatbeltArgsBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seatbeltArgsBuilder.js","sourceRoot":"","sources":["../../../../src/sandbox/macos/seatbeltArgsBuilder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACL,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAc1B;;;;GAIG;AACH,SAAS,WAAW,CAAC,CAAS;IAC5B,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,KAAK,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAClC,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;gBACpB,OAAO,CAAC,CAAC;YACX,CAAC;YACD,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7D,CAAC;QACD,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAA4B;IAC5D,IAAI,OAAO,GAAG,qBAAqB,GAAG,IAAI,CAAC;IAC3C,MAAM,IAAI,GAAa,EAAE,CAAC;IAE1B,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACrD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,aAAa,aAAa,EAAE,CAAC,CAAC;IAE9C,MAAM,OAAO,GAAG,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,OAAO,EAAE,CAAC,CAAC;IAErC,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrD,MAAM,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;YACzD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,IAAI,WAAW,EAAE,CAAC,CAAC;YACpD,OAAO,IAAI,+DAA+D,CAAC,QAAQ,CAAC;QACtF,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;QAC1B,OAAO,IAAI,wBAAwB,CAAC;IACtC,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAE5B,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
7
|
+
import { buildSeatbeltArgs } from './seatbeltArgsBuilder.js';
|
|
8
|
+
import fs from 'node:fs';
|
|
9
|
+
import os from 'node:os';
|
|
10
|
+
describe('seatbeltArgsBuilder', () => {
|
|
11
|
+
it('should build a strict allowlist profile allowing the workspace via param', () => {
|
|
12
|
+
// Mock realpathSync to just return the path for testing
|
|
13
|
+
vi.spyOn(fs, 'realpathSync').mockImplementation((p) => p);
|
|
14
|
+
const args = buildSeatbeltArgs({ workspace: '/Users/test/workspace' });
|
|
15
|
+
expect(args[0]).toBe('-p');
|
|
16
|
+
const profile = args[1];
|
|
17
|
+
expect(profile).toContain('(version 1)');
|
|
18
|
+
expect(profile).toContain('(deny default)');
|
|
19
|
+
expect(profile).toContain('(allow process-exec)');
|
|
20
|
+
expect(profile).toContain('(subpath (param "WORKSPACE"))');
|
|
21
|
+
expect(profile).not.toContain('(allow network*)');
|
|
22
|
+
expect(args).toContain('-D');
|
|
23
|
+
expect(args).toContain('WORKSPACE=/Users/test/workspace');
|
|
24
|
+
expect(args).toContain(`TMPDIR=${os.tmpdir()}`);
|
|
25
|
+
vi.restoreAllMocks();
|
|
26
|
+
});
|
|
27
|
+
it('should allow network when networkAccess is true', () => {
|
|
28
|
+
const args = buildSeatbeltArgs({ workspace: '/test', networkAccess: true });
|
|
29
|
+
const profile = args[1];
|
|
30
|
+
expect(profile).toContain('(allow network*)');
|
|
31
|
+
});
|
|
32
|
+
it('should parameterize allowed paths and normalize them', () => {
|
|
33
|
+
vi.spyOn(fs, 'realpathSync').mockImplementation((p) => {
|
|
34
|
+
if (p === '/test/symlink')
|
|
35
|
+
return '/test/real_path';
|
|
36
|
+
return p;
|
|
37
|
+
});
|
|
38
|
+
const args = buildSeatbeltArgs({
|
|
39
|
+
workspace: '/test',
|
|
40
|
+
allowedPaths: ['/custom/path1', '/test/symlink'],
|
|
41
|
+
});
|
|
42
|
+
const profile = args[1];
|
|
43
|
+
expect(profile).toContain('(subpath (param "ALLOWED_PATH_0"))');
|
|
44
|
+
expect(profile).toContain('(subpath (param "ALLOWED_PATH_1"))');
|
|
45
|
+
expect(args).toContain('-D');
|
|
46
|
+
expect(args).toContain('ALLOWED_PATH_0=/custom/path1');
|
|
47
|
+
expect(args).toContain('ALLOWED_PATH_1=/test/real_path');
|
|
48
|
+
vi.restoreAllMocks();
|
|
49
|
+
});
|
|
50
|
+
it('should resolve parent directories if a file does not exist', () => {
|
|
51
|
+
vi.spyOn(fs, 'realpathSync').mockImplementation((p) => {
|
|
52
|
+
if (p === '/test/symlink/nonexistent.txt') {
|
|
53
|
+
const error = new Error('ENOENT');
|
|
54
|
+
Object.assign(error, { code: 'ENOENT' });
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
if (p === '/test/symlink') {
|
|
58
|
+
return '/test/real_path';
|
|
59
|
+
}
|
|
60
|
+
return p;
|
|
61
|
+
});
|
|
62
|
+
const args = buildSeatbeltArgs({
|
|
63
|
+
workspace: '/test/symlink/nonexistent.txt',
|
|
64
|
+
});
|
|
65
|
+
expect(args).toContain('WORKSPACE=/test/real_path/nonexistent.txt');
|
|
66
|
+
vi.restoreAllMocks();
|
|
67
|
+
});
|
|
68
|
+
it('should throw if realpathSync throws a non-ENOENT error', () => {
|
|
69
|
+
vi.spyOn(fs, 'realpathSync').mockImplementation(() => {
|
|
70
|
+
const error = new Error('Permission denied');
|
|
71
|
+
Object.assign(error, { code: 'EACCES' });
|
|
72
|
+
throw error;
|
|
73
|
+
});
|
|
74
|
+
expect(() => buildSeatbeltArgs({
|
|
75
|
+
workspace: '/test/workspace',
|
|
76
|
+
})).toThrow('Permission denied');
|
|
77
|
+
vi.restoreAllMocks();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
//# sourceMappingURL=seatbeltArgsBuilder.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seatbeltArgsBuilder.test.js","sourceRoot":"","sources":["../../../../src/sandbox/macos/seatbeltArgsBuilder.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,0EAA0E,EAAE,GAAG,EAAE;QAClF,wDAAwD;QACxD,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAW,CAAC,CAAC;QAEpE,MAAM,IAAI,GAAG,iBAAiB,CAAC,EAAE,SAAS,EAAE,uBAAuB,EAAE,CAAC,CAAC;QAEvE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACzC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC5C,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAClD,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,+BAA+B,CAAC,CAAC;QAC3D,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QAElD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,iCAAiC,CAAC,CAAC;QAC1D,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAEhD,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,IAAI,GAAG,iBAAiB,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5E,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,EAAE;YACpD,IAAI,CAAC,KAAK,eAAe;gBAAE,OAAO,iBAAiB,CAAC;YACpD,OAAO,CAAW,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,iBAAiB,CAAC;YAC7B,SAAS,EAAE,OAAO;YAClB,YAAY,EAAE,CAAC,eAAe,EAAE,eAAe,CAAC;SACjD,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,oCAAoC,CAAC,CAAC;QAChE,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,oCAAoC,CAAC,CAAC;QAEhE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAC;QACvD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gCAAgC,CAAC,CAAC;QAEzD,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,EAAE;YACpD,IAAI,CAAC,KAAK,+BAA+B,EAAE,CAAC;gBAC1C,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAClC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;gBACzC,MAAM,KAAK,CAAC;YACd,CAAC;YACD,IAAI,CAAC,KAAK,eAAe,EAAE,CAAC;gBAC1B,OAAO,iBAAiB,CAAC;YAC3B,CAAC;YACD,OAAO,CAAW,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,iBAAiB,CAAC;YAC7B,SAAS,EAAE,+BAA+B;SAC3C,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,2CAA2C,CAAC,CAAC;QACpE,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACnD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YAC7C,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;YACzC,MAAM,KAAK,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,GAAG,EAAE,CACV,iBAAiB,CAAC;YAChB,SAAS,EAAE,iBAAiB;SAC7B,CAAC,CACH,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAE/B,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|