@google/gemini-cli-core 0.36.0-preview.8 → 0.37.0-preview.0

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.
Files changed (472) hide show
  1. package/dist/docs/CONTRIBUTING.md +10 -7
  2. package/dist/docs/assets/theme-tokyonight-dark.png +0 -0
  3. package/dist/docs/changelogs/index.md +24 -0
  4. package/dist/docs/changelogs/latest.md +366 -459
  5. package/dist/docs/changelogs/preview.md +362 -356
  6. package/dist/docs/cli/acp-mode.md +126 -0
  7. package/dist/docs/cli/cli-reference.md +1 -1
  8. package/dist/docs/cli/notifications.md +5 -5
  9. package/dist/docs/cli/plan-mode.md +12 -8
  10. package/dist/docs/cli/sandbox.md +1 -1
  11. package/dist/docs/cli/settings.md +14 -13
  12. package/dist/docs/cli/themes.md +5 -0
  13. package/dist/docs/core/index.md +2 -2
  14. package/dist/docs/core/subagents.md +134 -23
  15. package/dist/docs/get-started/gemini-3.md +1 -1
  16. package/dist/docs/get-started/index.md +127 -1
  17. package/dist/docs/ide-integration/index.md +99 -24
  18. package/dist/docs/index.md +0 -2
  19. package/dist/docs/redirects.json +1 -0
  20. package/dist/docs/reference/commands.md +1 -3
  21. package/dist/docs/reference/configuration.md +182 -91
  22. package/dist/docs/reference/keyboard-shortcuts.md +14 -6
  23. package/dist/docs/reference/policy-engine.md +16 -30
  24. package/dist/docs/reference/tools.md +56 -23
  25. package/dist/docs/resources/quota-and-pricing.md +23 -9
  26. package/dist/docs/sidebar.json +11 -4
  27. package/dist/docs/tools/planning.md +6 -4
  28. package/dist/src/agents/agentLoader.d.ts +12 -12
  29. package/dist/src/agents/agentLoader.js +1 -0
  30. package/dist/src/agents/agentLoader.js.map +1 -1
  31. package/dist/src/agents/browser/automationOverlay.js +2 -10
  32. package/dist/src/agents/browser/automationOverlay.js.map +1 -1
  33. package/dist/src/agents/browser/browserAgentDefinition.js +10 -3
  34. package/dist/src/agents/browser/browserAgentDefinition.js.map +1 -1
  35. package/dist/src/agents/browser/browserAgentFactory.d.ts +4 -4
  36. package/dist/src/agents/browser/browserAgentFactory.js +15 -29
  37. package/dist/src/agents/browser/browserAgentFactory.js.map +1 -1
  38. package/dist/src/agents/browser/browserAgentFactory.test.js +41 -24
  39. package/dist/src/agents/browser/browserAgentFactory.test.js.map +1 -1
  40. package/dist/src/agents/browser/browserAgentInvocation.d.ts +1 -0
  41. package/dist/src/agents/browser/browserAgentInvocation.js +60 -27
  42. package/dist/src/agents/browser/browserAgentInvocation.js.map +1 -1
  43. package/dist/src/agents/browser/browserAgentInvocation.test.js +59 -5
  44. package/dist/src/agents/browser/browserAgentInvocation.test.js.map +1 -1
  45. package/dist/src/agents/browser/browserManager.d.ts +51 -8
  46. package/dist/src/agents/browser/browserManager.js +242 -70
  47. package/dist/src/agents/browser/browserManager.js.map +1 -1
  48. package/dist/src/agents/browser/browserManager.test.js +384 -17
  49. package/dist/src/agents/browser/browserManager.test.js.map +1 -1
  50. package/dist/src/agents/browser/inputBlocker.d.ts +4 -4
  51. package/dist/src/agents/browser/inputBlocker.js +8 -18
  52. package/dist/src/agents/browser/inputBlocker.js.map +1 -1
  53. package/dist/src/agents/browser/inputBlocker.test.js +31 -3
  54. package/dist/src/agents/browser/inputBlocker.test.js.map +1 -1
  55. package/dist/src/agents/browser/mcpToolWrapper.d.ts +1 -1
  56. package/dist/src/agents/browser/mcpToolWrapper.js +9 -6
  57. package/dist/src/agents/browser/mcpToolWrapper.js.map +1 -1
  58. package/dist/src/agents/browser/mcpToolWrapper.test.js +2 -2
  59. package/dist/src/agents/browser/mcpToolWrapper.test.js.map +1 -1
  60. package/dist/src/agents/browser/snapshotSuperseder.d.ts +31 -0
  61. package/dist/src/agents/browser/snapshotSuperseder.js +101 -0
  62. package/dist/src/agents/browser/snapshotSuperseder.js.map +1 -0
  63. package/dist/src/agents/browser/snapshotSuperseder.test.js +158 -0
  64. package/dist/src/agents/browser/snapshotSuperseder.test.js.map +1 -0
  65. package/dist/src/agents/local-executor.d.ts +4 -0
  66. package/dist/src/agents/local-executor.js +46 -19
  67. package/dist/src/agents/local-executor.js.map +1 -1
  68. package/dist/src/agents/local-executor.test.js +118 -18
  69. package/dist/src/agents/local-executor.test.js.map +1 -1
  70. package/dist/src/agents/local-invocation.d.ts +1 -0
  71. package/dist/src/agents/local-invocation.js +19 -9
  72. package/dist/src/agents/local-invocation.js.map +1 -1
  73. package/dist/src/agents/local-invocation.test.js +24 -0
  74. package/dist/src/agents/local-invocation.test.js.map +1 -1
  75. package/dist/src/agents/registry.js +16 -1
  76. package/dist/src/agents/registry.js.map +1 -1
  77. package/dist/src/agents/registry.test.js +67 -0
  78. package/dist/src/agents/registry.test.js.map +1 -1
  79. package/dist/src/agents/types.d.ts +9 -0
  80. package/dist/src/agents/types.js.map +1 -1
  81. package/dist/src/code_assist/oauth2.js +8 -3
  82. package/dist/src/code_assist/oauth2.js.map +1 -1
  83. package/dist/src/code_assist/oauth2.test.js +57 -0
  84. package/dist/src/code_assist/oauth2.test.js.map +1 -1
  85. package/dist/src/code_assist/setup.js +5 -2
  86. package/dist/src/code_assist/setup.js.map +1 -1
  87. package/dist/src/code_assist/setup.test.js +27 -1
  88. package/dist/src/code_assist/setup.test.js.map +1 -1
  89. package/dist/src/code_assist/types.d.ts +80 -80
  90. package/dist/src/config/agent-loop-context.d.ts +2 -0
  91. package/dist/src/config/config.d.ts +81 -16
  92. package/dist/src/config/config.js +146 -50
  93. package/dist/src/config/config.js.map +1 -1
  94. package/dist/src/config/config.test.js +89 -2
  95. package/dist/src/config/config.test.js.map +1 -1
  96. package/dist/src/config/defaultModelConfigs.js +9 -0
  97. package/dist/src/config/defaultModelConfigs.js.map +1 -1
  98. package/dist/src/config/memory.d.ts +1 -0
  99. package/dist/src/config/memory.js +6 -0
  100. package/dist/src/config/memory.js.map +1 -1
  101. package/dist/src/config/storage.d.ts +1 -0
  102. package/dist/src/config/storage.js +4 -0
  103. package/dist/src/config/storage.js.map +1 -1
  104. package/dist/src/config/storage.test.js +5 -0
  105. package/dist/src/config/storage.test.js.map +1 -1
  106. package/dist/src/config/topicState.d.ts +21 -0
  107. package/dist/src/config/topicState.js +41 -0
  108. package/dist/src/config/topicState.js.map +1 -0
  109. package/dist/src/confirmation-bus/types.d.ts +9 -2
  110. package/dist/src/confirmation-bus/types.js +1 -0
  111. package/dist/src/confirmation-bus/types.js.map +1 -1
  112. package/dist/src/context/agentHistoryProvider.d.ts +45 -0
  113. package/dist/src/context/agentHistoryProvider.js +298 -0
  114. package/dist/src/context/agentHistoryProvider.js.map +1 -0
  115. package/dist/src/context/agentHistoryProvider.test.d.ts +6 -0
  116. package/dist/src/context/agentHistoryProvider.test.js +394 -0
  117. package/dist/src/context/agentHistoryProvider.test.js.map +1 -0
  118. package/dist/src/context/chatCompressionService.js.map +1 -0
  119. package/dist/src/context/chatCompressionService.test.js.map +1 -0
  120. package/dist/src/{services → context}/contextManager.d.ts +2 -0
  121. package/dist/src/{services → context}/contextManager.js +18 -9
  122. package/dist/src/context/contextManager.js.map +1 -0
  123. package/dist/src/{services → context}/contextManager.test.js +21 -6
  124. package/dist/src/context/contextManager.test.js.map +1 -0
  125. package/dist/src/context/toolDistillationService.d.ts +38 -0
  126. package/dist/src/context/toolDistillationService.js +170 -0
  127. package/dist/src/context/toolDistillationService.js.map +1 -0
  128. package/dist/src/context/toolDistillationService.test.d.ts +6 -0
  129. package/dist/src/context/toolDistillationService.test.js +83 -0
  130. package/dist/src/context/toolDistillationService.test.js.map +1 -0
  131. package/dist/src/{services → context}/toolOutputMaskingService.d.ts +2 -2
  132. package/dist/src/{services → context}/toolOutputMaskingService.js +7 -7
  133. package/dist/src/context/toolOutputMaskingService.js.map +1 -0
  134. package/dist/src/context/toolOutputMaskingService.test.d.ts +6 -0
  135. package/dist/src/{services → context}/toolOutputMaskingService.test.js +4 -5
  136. package/dist/src/context/toolOutputMaskingService.test.js.map +1 -0
  137. package/dist/src/context/truncation.d.ts +26 -0
  138. package/dist/src/context/truncation.js +102 -0
  139. package/dist/src/context/truncation.js.map +1 -0
  140. package/dist/src/core/client.d.ts +3 -1
  141. package/dist/src/core/client.js +23 -13
  142. package/dist/src/core/client.js.map +1 -1
  143. package/dist/src/core/client.test.js +29 -34
  144. package/dist/src/core/client.test.js.map +1 -1
  145. package/dist/src/core/contentGenerator.d.ts +0 -1
  146. package/dist/src/core/contentGenerator.js +2 -28
  147. package/dist/src/core/contentGenerator.js.map +1 -1
  148. package/dist/src/core/contentGenerator.test.js +1 -101
  149. package/dist/src/core/contentGenerator.test.js.map +1 -1
  150. package/dist/src/core/geminiChat.js +4 -5
  151. package/dist/src/core/geminiChat.js.map +1 -1
  152. package/dist/src/core/geminiChat.test.js +71 -18
  153. package/dist/src/core/geminiChat.test.js.map +1 -1
  154. package/dist/src/core/prompts-substitution.test.js +5 -0
  155. package/dist/src/core/prompts-substitution.test.js.map +1 -1
  156. package/dist/src/core/prompts.test.js +3 -0
  157. package/dist/src/core/prompts.test.js.map +1 -1
  158. package/dist/src/generated/git-commit.d.ts +2 -2
  159. package/dist/src/generated/git-commit.js +2 -2
  160. package/dist/src/index.d.ts +7 -3
  161. package/dist/src/index.js +9 -5
  162. package/dist/src/index.js.map +1 -1
  163. package/dist/src/policy/config.d.ts +1 -1
  164. package/dist/src/policy/config.js +5 -2
  165. package/dist/src/policy/config.js.map +1 -1
  166. package/dist/src/policy/policies/discovered.toml +7 -0
  167. package/dist/src/policy/policies/non-interactive.toml +7 -0
  168. package/dist/src/policy/policies/plan.toml +25 -0
  169. package/dist/src/policy/policies/read-only.toml +6 -0
  170. package/dist/src/policy/policies/sandbox-default.toml +3 -2
  171. package/dist/src/policy/policies/write.toml +21 -0
  172. package/dist/src/policy/policies/yolo.toml +1 -1
  173. package/dist/src/policy/policy-engine.d.ts +2 -4
  174. package/dist/src/policy/policy-engine.js +24 -37
  175. package/dist/src/policy/policy-engine.js.map +1 -1
  176. package/dist/src/policy/policy-engine.test.js +107 -29
  177. package/dist/src/policy/policy-engine.test.js.map +1 -1
  178. package/dist/src/policy/topic-policy.test.d.ts +6 -0
  179. package/dist/src/policy/topic-policy.test.js +48 -0
  180. package/dist/src/policy/topic-policy.test.js.map +1 -0
  181. package/dist/src/policy/types.d.ts +3 -6
  182. package/dist/src/policy/types.js.map +1 -1
  183. package/dist/src/prompts/promptProvider.js +20 -4
  184. package/dist/src/prompts/promptProvider.js.map +1 -1
  185. package/dist/src/prompts/promptProvider.test.js +84 -1
  186. package/dist/src/prompts/promptProvider.test.js.map +1 -1
  187. package/dist/src/prompts/snippets-memory-manager.test.js +1 -1
  188. package/dist/src/prompts/snippets-memory-manager.test.js.map +1 -1
  189. package/dist/src/prompts/snippets.d.ts +3 -4
  190. package/dist/src/prompts/snippets.js +33 -51
  191. package/dist/src/prompts/snippets.js.map +1 -1
  192. package/dist/src/prompts/snippets.legacy.d.ts +6 -4
  193. package/dist/src/prompts/snippets.legacy.js +32 -7
  194. package/dist/src/prompts/snippets.legacy.js.map +1 -1
  195. package/dist/src/sandbox/linux/LinuxSandboxManager.d.ts +11 -1
  196. package/dist/src/sandbox/linux/LinuxSandboxManager.js +261 -27
  197. package/dist/src/sandbox/linux/LinuxSandboxManager.js.map +1 -1
  198. package/dist/src/sandbox/linux/LinuxSandboxManager.test.js +430 -125
  199. package/dist/src/sandbox/linux/LinuxSandboxManager.test.js.map +1 -1
  200. package/dist/src/sandbox/macos/MacOsSandboxManager.d.ts +7 -22
  201. package/dist/src/sandbox/macos/MacOsSandboxManager.js +58 -57
  202. package/dist/src/sandbox/macos/MacOsSandboxManager.js.map +1 -1
  203. package/dist/src/sandbox/macos/MacOsSandboxManager.test.js +148 -103
  204. package/dist/src/sandbox/macos/MacOsSandboxManager.test.js.map +1 -1
  205. package/dist/src/sandbox/macos/baseProfile.d.ts +1 -1
  206. package/dist/src/sandbox/macos/baseProfile.js +0 -6
  207. package/dist/src/sandbox/macos/baseProfile.js.map +1 -1
  208. package/dist/src/sandbox/macos/seatbeltArgsBuilder.d.ts +10 -10
  209. package/dist/src/sandbox/macos/seatbeltArgsBuilder.js +80 -92
  210. package/dist/src/sandbox/macos/seatbeltArgsBuilder.js.map +1 -1
  211. package/dist/src/sandbox/macos/seatbeltArgsBuilder.test.js +135 -99
  212. package/dist/src/sandbox/macos/seatbeltArgsBuilder.test.js.map +1 -1
  213. package/dist/src/sandbox/{macos → utils}/commandSafety.d.ts +11 -0
  214. package/dist/src/sandbox/{macos → utils}/commandSafety.js +47 -14
  215. package/dist/src/sandbox/utils/commandSafety.js.map +1 -0
  216. package/dist/src/sandbox/utils/commandUtils.d.ts +9 -0
  217. package/dist/src/sandbox/utils/commandUtils.js +57 -0
  218. package/dist/src/sandbox/utils/commandUtils.js.map +1 -0
  219. package/dist/src/sandbox/utils/fsUtils.d.ts +11 -0
  220. package/dist/src/sandbox/utils/fsUtils.js +82 -0
  221. package/dist/src/sandbox/utils/fsUtils.js.map +1 -0
  222. package/dist/src/sandbox/utils/sandboxDenialUtils.d.ts +12 -0
  223. package/dist/src/sandbox/utils/sandboxDenialUtils.js +68 -0
  224. package/dist/src/sandbox/utils/sandboxDenialUtils.js.map +1 -0
  225. package/dist/src/sandbox/utils/sandboxDenialUtils.test.d.ts +6 -0
  226. package/dist/src/sandbox/utils/sandboxDenialUtils.test.js +37 -0
  227. package/dist/src/sandbox/utils/sandboxDenialUtils.test.js.map +1 -0
  228. package/dist/src/sandbox/utils/sandboxReadWriteUtils.d.ts +5 -0
  229. package/dist/src/sandbox/utils/sandboxReadWriteUtils.js +60 -0
  230. package/dist/src/sandbox/utils/sandboxReadWriteUtils.js.map +1 -0
  231. package/dist/src/sandbox/windows/GeminiSandbox.cs +257 -216
  232. package/dist/src/sandbox/windows/WindowsSandboxManager.d.ts +12 -2
  233. package/dist/src/sandbox/windows/WindowsSandboxManager.js +250 -38
  234. package/dist/src/sandbox/windows/WindowsSandboxManager.js.map +1 -1
  235. package/dist/src/sandbox/windows/WindowsSandboxManager.test.js +326 -9
  236. package/dist/src/sandbox/windows/WindowsSandboxManager.test.js.map +1 -1
  237. package/dist/src/sandbox/windows/commandSafety.d.ts +19 -0
  238. package/dist/src/sandbox/windows/commandSafety.js +128 -0
  239. package/dist/src/sandbox/windows/commandSafety.js.map +1 -0
  240. package/dist/src/sandbox/windows/commandSafety.test.d.ts +6 -0
  241. package/dist/src/sandbox/windows/commandSafety.test.js +42 -0
  242. package/dist/src/sandbox/windows/commandSafety.test.js.map +1 -0
  243. package/dist/src/sandbox/windows/windowsSandboxDenialUtils.d.ts +12 -0
  244. package/dist/src/sandbox/windows/windowsSandboxDenialUtils.js +68 -0
  245. package/dist/src/sandbox/windows/windowsSandboxDenialUtils.js.map +1 -0
  246. package/dist/src/sandbox/windows/windowsSandboxDenialUtils.test.d.ts +6 -0
  247. package/dist/src/sandbox/windows/windowsSandboxDenialUtils.test.js +68 -0
  248. package/dist/src/sandbox/windows/windowsSandboxDenialUtils.test.js.map +1 -0
  249. package/dist/src/scheduler/scheduler.js +12 -2
  250. package/dist/src/scheduler/scheduler.js.map +1 -1
  251. package/dist/src/scheduler/scheduler.test.js +52 -0
  252. package/dist/src/scheduler/scheduler.test.js.map +1 -1
  253. package/dist/src/scheduler/scheduler_hooks.test.js +1 -0
  254. package/dist/src/scheduler/scheduler_hooks.test.js.map +1 -1
  255. package/dist/src/scheduler/state-manager.js +1 -1
  256. package/dist/src/scheduler/state-manager.js.map +1 -1
  257. package/dist/src/scheduler/state-manager.test.js +10 -0
  258. package/dist/src/scheduler/state-manager.test.js.map +1 -1
  259. package/dist/src/scheduler/tool-executor.js +7 -2
  260. package/dist/src/scheduler/tool-executor.js.map +1 -1
  261. package/dist/src/scheduler/tool-executor.test.js +38 -0
  262. package/dist/src/scheduler/tool-executor.test.js.map +1 -1
  263. package/dist/src/scheduler/types.d.ts +4 -2
  264. package/dist/src/services/chatRecordingService.d.ts +1 -13
  265. package/dist/src/services/chatRecordingService.js +45 -46
  266. package/dist/src/services/chatRecordingService.js.map +1 -1
  267. package/dist/src/services/chatRecordingService.test.js +79 -10
  268. package/dist/src/services/chatRecordingService.test.js.map +1 -1
  269. package/dist/src/services/executionLifecycleService.d.ts +43 -6
  270. package/dist/src/services/executionLifecycleService.js +49 -12
  271. package/dist/src/services/executionLifecycleService.js.map +1 -1
  272. package/dist/src/services/executionLifecycleService.test.js +157 -3
  273. package/dist/src/services/executionLifecycleService.test.js.map +1 -1
  274. package/dist/src/services/fileDiscoveryService.d.ts +17 -2
  275. package/dist/src/services/fileDiscoveryService.js +84 -20
  276. package/dist/src/services/fileDiscoveryService.js.map +1 -1
  277. package/dist/src/services/fileDiscoveryService.test.js +67 -1
  278. package/dist/src/services/fileDiscoveryService.test.js.map +1 -1
  279. package/dist/src/services/modelConfigService.d.ts +11 -0
  280. package/dist/src/services/modelConfigService.js +67 -0
  281. package/dist/src/services/modelConfigService.js.map +1 -1
  282. package/dist/src/services/modelConfigService.test.js +30 -0
  283. package/dist/src/services/modelConfigService.test.js.map +1 -1
  284. package/dist/src/services/sandboxManager.d.ts +90 -8
  285. package/dist/src/services/sandboxManager.integration.test.js +438 -0
  286. package/dist/src/services/sandboxManager.integration.test.js.map +1 -0
  287. package/dist/src/services/sandboxManager.js +156 -13
  288. package/dist/src/services/sandboxManager.js.map +1 -1
  289. package/dist/src/services/sandboxManager.test.js +373 -117
  290. package/dist/src/services/sandboxManager.test.js.map +1 -1
  291. package/dist/src/services/sandboxManagerFactory.d.ts +2 -3
  292. package/dist/src/services/sandboxManagerFactory.js +10 -17
  293. package/dist/src/services/sandboxManagerFactory.js.map +1 -1
  294. package/dist/src/services/sandboxedFileSystemService.d.ts +1 -0
  295. package/dist/src/services/sandboxedFileSystemService.js +32 -3
  296. package/dist/src/services/sandboxedFileSystemService.js.map +1 -1
  297. package/dist/src/services/sandboxedFileSystemService.test.js +83 -12
  298. package/dist/src/services/sandboxedFileSystemService.test.js.map +1 -1
  299. package/dist/src/services/shellExecutionService.d.ts +2 -0
  300. package/dist/src/services/shellExecutionService.js +45 -16
  301. package/dist/src/services/shellExecutionService.js.map +1 -1
  302. package/dist/src/services/shellExecutionService.test.js +5 -4
  303. package/dist/src/services/shellExecutionService.test.js.map +1 -1
  304. package/dist/src/services/test-data/resolved-aliases-retry.golden.json +4 -0
  305. package/dist/src/services/test-data/resolved-aliases.golden.json +4 -0
  306. package/dist/src/services/types.d.ts +14 -0
  307. package/dist/src/services/types.js +7 -0
  308. package/dist/src/services/types.js.map +1 -0
  309. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +6 -0
  310. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  311. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +5 -1
  312. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
  313. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +2 -1
  314. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +3 -1
  315. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  316. package/dist/src/telemetry/loggers.js +1 -1
  317. package/dist/src/telemetry/loggers.js.map +1 -1
  318. package/dist/src/telemetry/loggers.test.js +8 -3
  319. package/dist/src/telemetry/loggers.test.js.map +1 -1
  320. package/dist/src/telemetry/metrics.d.ts +10 -1
  321. package/dist/src/telemetry/metrics.js +19 -4
  322. package/dist/src/telemetry/metrics.js.map +1 -1
  323. package/dist/src/telemetry/metrics.test.js +44 -0
  324. package/dist/src/telemetry/metrics.test.js.map +1 -1
  325. package/dist/src/telemetry/types.d.ts +3 -3
  326. package/dist/src/telemetry/types.js +9 -4
  327. package/dist/src/telemetry/types.js.map +1 -1
  328. package/dist/src/test-utils/mock-message-bus.d.ts +1 -1
  329. package/dist/src/test-utils/mock-message-bus.js +1 -1
  330. package/dist/src/test-utils/mock-message-bus.js.map +1 -1
  331. package/dist/src/tools/definitions/base-declarations.d.ts +6 -0
  332. package/dist/src/tools/definitions/base-declarations.js +7 -0
  333. package/dist/src/tools/definitions/base-declarations.js.map +1 -1
  334. package/dist/src/tools/definitions/coreTools.d.ts +2 -1
  335. package/dist/src/tools/definitions/coreTools.js +9 -3
  336. package/dist/src/tools/definitions/coreTools.js.map +1 -1
  337. package/dist/src/tools/definitions/dynamic-declaration-helpers.d.ts +4 -0
  338. package/dist/src/tools/definitions/dynamic-declaration-helpers.js +29 -2
  339. package/dist/src/tools/definitions/dynamic-declaration-helpers.js.map +1 -1
  340. package/dist/src/tools/definitions/model-family-sets/default-legacy.js +11 -6
  341. package/dist/src/tools/definitions/model-family-sets/default-legacy.js.map +1 -1
  342. package/dist/src/tools/definitions/model-family-sets/gemini-3.js +10 -4
  343. package/dist/src/tools/definitions/model-family-sets/gemini-3.js.map +1 -1
  344. package/dist/src/tools/definitions/trackerTools.js +3 -3
  345. package/dist/src/tools/definitions/trackerTools.js.map +1 -1
  346. package/dist/src/tools/definitions/types.d.ts +1 -0
  347. package/dist/src/tools/enter-plan-mode.js +15 -0
  348. package/dist/src/tools/enter-plan-mode.js.map +1 -1
  349. package/dist/src/tools/enter-plan-mode.test.js +25 -0
  350. package/dist/src/tools/enter-plan-mode.test.js.map +1 -1
  351. package/dist/src/tools/grep-utils.d.ts +2 -1
  352. package/dist/src/tools/grep-utils.js +22 -3
  353. package/dist/src/tools/grep-utils.js.map +1 -1
  354. package/dist/src/tools/grep.js +16 -3
  355. package/dist/src/tools/grep.js.map +1 -1
  356. package/dist/src/tools/grep.test.js +34 -6
  357. package/dist/src/tools/grep.test.js.map +1 -1
  358. package/dist/src/tools/ls.js +6 -4
  359. package/dist/src/tools/ls.js.map +1 -1
  360. package/dist/src/tools/ls.test.js +22 -7
  361. package/dist/src/tools/ls.test.js.map +1 -1
  362. package/dist/src/tools/mcp-client-manager.js +6 -3
  363. package/dist/src/tools/mcp-client-manager.js.map +1 -1
  364. package/dist/src/tools/mcp-client-manager.test.js +35 -0
  365. package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
  366. package/dist/src/tools/memoryTool.d.ts +9 -2
  367. package/dist/src/tools/memoryTool.js +39 -15
  368. package/dist/src/tools/memoryTool.js.map +1 -1
  369. package/dist/src/tools/memoryTool.test.js +61 -2
  370. package/dist/src/tools/memoryTool.test.js.map +1 -1
  371. package/dist/src/tools/read-many-files.js +12 -4
  372. package/dist/src/tools/read-many-files.js.map +1 -1
  373. package/dist/src/tools/read-many-files.test.js +17 -17
  374. package/dist/src/tools/read-many-files.test.js.map +1 -1
  375. package/dist/src/tools/ripGrep.js +14 -1
  376. package/dist/src/tools/ripGrep.js.map +1 -1
  377. package/dist/src/tools/ripGrep.test.js +9 -9
  378. package/dist/src/tools/ripGrep.test.js.map +1 -1
  379. package/dist/src/tools/shell.d.ts +10 -0
  380. package/dist/src/tools/shell.js +97 -124
  381. package/dist/src/tools/shell.js.map +1 -1
  382. package/dist/src/tools/shell.test.js +22 -3
  383. package/dist/src/tools/shell.test.js.map +1 -1
  384. package/dist/src/tools/tool-names.d.ts +4 -4
  385. package/dist/src/tools/tool-names.js +5 -3
  386. package/dist/src/tools/tool-names.js.map +1 -1
  387. package/dist/src/tools/tool-registry.js +11 -1
  388. package/dist/src/tools/tool-registry.js.map +1 -1
  389. package/dist/src/tools/tool-registry.test.js +43 -1
  390. package/dist/src/tools/tool-registry.test.js.map +1 -1
  391. package/dist/src/tools/tools.d.ts +12 -1
  392. package/dist/src/tools/tools.js +15 -0
  393. package/dist/src/tools/tools.js.map +1 -1
  394. package/dist/src/tools/tools.test.js +42 -1
  395. package/dist/src/tools/tools.test.js.map +1 -1
  396. package/dist/src/tools/topicTool.d.ts +29 -0
  397. package/dist/src/tools/topicTool.js +72 -0
  398. package/dist/src/tools/topicTool.js.map +1 -0
  399. package/dist/src/tools/topicTool.test.d.ts +6 -0
  400. package/dist/src/tools/topicTool.test.js +105 -0
  401. package/dist/src/tools/topicTool.test.js.map +1 -0
  402. package/dist/src/tools/web-fetch.js +38 -20
  403. package/dist/src/tools/web-fetch.js.map +1 -1
  404. package/dist/src/tools/web-fetch.test.js +28 -0
  405. package/dist/src/tools/web-fetch.test.js.map +1 -1
  406. package/dist/src/utils/checkpointUtils.d.ts +4 -4
  407. package/dist/src/utils/errors.d.ts +3 -0
  408. package/dist/src/utils/errors.js +28 -6
  409. package/dist/src/utils/errors.js.map +1 -1
  410. package/dist/src/utils/errors.test.js +23 -0
  411. package/dist/src/utils/errors.test.js.map +1 -1
  412. package/dist/src/utils/getFolderStructure.js +1 -1
  413. package/dist/src/utils/getFolderStructure.js.map +1 -1
  414. package/dist/src/utils/gitIgnoreParser.d.ts +2 -2
  415. package/dist/src/utils/gitIgnoreParser.js +28 -50
  416. package/dist/src/utils/gitIgnoreParser.js.map +1 -1
  417. package/dist/src/utils/gitIgnoreParser.test.js +51 -185
  418. package/dist/src/utils/gitIgnoreParser.test.js.map +1 -1
  419. package/dist/src/utils/ignoreFileParser.d.ts +2 -2
  420. package/dist/src/utils/ignoreFileParser.js +6 -17
  421. package/dist/src/utils/ignoreFileParser.js.map +1 -1
  422. package/dist/src/utils/ignoreFileParser.test.js +40 -132
  423. package/dist/src/utils/ignoreFileParser.test.js.map +1 -1
  424. package/dist/src/utils/ignorePathUtils.d.ts +11 -0
  425. package/dist/src/utils/ignorePathUtils.js +39 -0
  426. package/dist/src/utils/ignorePathUtils.js.map +1 -0
  427. package/dist/src/utils/ignorePathUtils.test.d.ts +6 -0
  428. package/dist/src/utils/ignorePathUtils.test.js +70 -0
  429. package/dist/src/utils/ignorePathUtils.test.js.map +1 -0
  430. package/dist/src/utils/memoryDiscovery.d.ts +6 -4
  431. package/dist/src/utils/memoryDiscovery.js +66 -41
  432. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  433. package/dist/src/utils/memoryDiscovery.test.js +40 -0
  434. package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
  435. package/dist/src/utils/memoryImportProcessor.d.ts +1 -1
  436. package/dist/src/utils/memoryImportProcessor.js +24 -15
  437. package/dist/src/utils/memoryImportProcessor.js.map +1 -1
  438. package/dist/src/utils/sessionOperations.d.ts +19 -0
  439. package/dist/src/utils/sessionOperations.js +101 -0
  440. package/dist/src/utils/sessionOperations.js.map +1 -0
  441. package/dist/src/utils/sessionOperations.test.d.ts +6 -0
  442. package/dist/src/utils/sessionOperations.test.js +92 -0
  443. package/dist/src/utils/sessionOperations.test.js.map +1 -0
  444. package/dist/src/utils/shell-utils.d.ts +15 -0
  445. package/dist/src/utils/shell-utils.js +43 -2
  446. package/dist/src/utils/shell-utils.js.map +1 -1
  447. package/dist/src/utils/textUtils.d.ts +8 -0
  448. package/dist/src/utils/textUtils.js +16 -0
  449. package/dist/src/utils/textUtils.js.map +1 -1
  450. package/dist/src/utils/tokenCalculation.d.ts +2 -0
  451. package/dist/src/utils/tokenCalculation.js +2 -2
  452. package/dist/src/utils/tokenCalculation.js.map +1 -1
  453. package/dist/tsconfig.tsbuildinfo +1 -1
  454. package/package.json +1 -1
  455. package/dist/docs/get-started/examples.md +0 -141
  456. package/dist/google-gemini-cli-core-0.36.0-preview.7.tgz +0 -0
  457. package/dist/src/sandbox/macos/MacOsSandboxManager.integration.test.js +0 -164
  458. package/dist/src/sandbox/macos/MacOsSandboxManager.integration.test.js.map +0 -1
  459. package/dist/src/sandbox/macos/commandSafety.js.map +0 -1
  460. package/dist/src/services/chatCompressionService.js.map +0 -1
  461. package/dist/src/services/chatCompressionService.test.js.map +0 -1
  462. package/dist/src/services/contextManager.js.map +0 -1
  463. package/dist/src/services/contextManager.test.js.map +0 -1
  464. package/dist/src/services/toolOutputMaskingService.js.map +0 -1
  465. package/dist/src/services/toolOutputMaskingService.test.js.map +0 -1
  466. /package/dist/src/{services/toolOutputMaskingService.test.d.ts → agents/browser/snapshotSuperseder.test.d.ts} +0 -0
  467. /package/dist/src/{services → context}/chatCompressionService.d.ts +0 -0
  468. /package/dist/src/{services → context}/chatCompressionService.js +0 -0
  469. /package/dist/src/{services → context}/chatCompressionService.test.d.ts +0 -0
  470. /package/dist/src/{services → context}/chatCompressionService.test.js +0 -0
  471. /package/dist/src/{services → context}/contextManager.test.d.ts +0 -0
  472. /package/dist/src/{sandbox/macos/MacOsSandboxManager.integration.test.d.ts → services/sandboxManager.integration.test.d.ts} +0 -0
@@ -5,45 +5,28 @@
5
5
  */
6
6
 
7
7
  using System;
8
- using System.Runtime.InteropServices;
9
8
  using System.Collections.Generic;
10
9
  using System.Diagnostics;
11
- using System.Security.Principal;
12
10
  using System.IO;
11
+ using System.Runtime.InteropServices;
12
+ using System.Security;
13
+ using System.Security.AccessControl;
14
+ using System.Security.Principal;
15
+ using System.Text;
13
16
 
17
+ /**
18
+ * A native C# helper for the Gemini CLI sandbox on Windows.
19
+ * This helper uses Restricted Tokens and Job Objects to isolate processes.
20
+ * It also supports internal commands for safe file I/O within the sandbox.
21
+ */
14
22
  public class GeminiSandbox {
15
- [StructLayout(LayoutKind.Sequential)]
16
- public struct STARTUPINFO {
17
- public uint cb;
18
- public string lpReserved;
19
- public string lpDesktop;
20
- public string lpTitle;
21
- public uint dwX;
22
- public uint dwY;
23
- public uint dwXSize;
24
- public uint dwYSize;
25
- public uint dwXCountChars;
26
- public uint dwYCountChars;
27
- public uint dwFillAttribute;
28
- public uint dwFlags;
29
- public ushort wShowWindow;
30
- public ushort cbReserved2;
31
- public IntPtr lpReserved2;
32
- public IntPtr hStdInput;
33
- public IntPtr hStdOutput;
34
- public IntPtr hStdError;
35
- }
36
-
37
- [StructLayout(LayoutKind.Sequential)]
38
- public struct PROCESS_INFORMATION {
39
- public IntPtr hProcess;
40
- public IntPtr hThread;
41
- public uint dwProcessId;
42
- public uint dwThreadId;
43
- }
23
+ // P/Invoke constants and structures
24
+ private const uint JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x00002000;
25
+ private const uint JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION = 0x00000400;
26
+ private const uint JOB_OBJECT_LIMIT_ACTIVE_PROCESS = 0x00000008;
44
27
 
45
28
  [StructLayout(LayoutKind.Sequential)]
46
- public struct JOBOBJECT_BASIC_LIMIT_INFORMATION {
29
+ struct JOBOBJECT_BASIC_LIMIT_INFORMATION {
47
30
  public Int64 PerProcessUserTimeLimit;
48
31
  public Int64 PerJobUserTimeLimit;
49
32
  public uint LimitFlags;
@@ -56,17 +39,7 @@ public class GeminiSandbox {
56
39
  }
57
40
 
58
41
  [StructLayout(LayoutKind.Sequential)]
59
- public struct IO_COUNTERS {
60
- public ulong ReadOperationCount;
61
- public ulong WriteOperationCount;
62
- public ulong OtherOperationCount;
63
- public ulong ReadTransferCount;
64
- public ulong WriteTransferCount;
65
- public ulong OtherTransferCount;
66
- }
67
-
68
- [StructLayout(LayoutKind.Sequential)]
69
- public struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION {
42
+ struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION {
70
43
  public JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;
71
44
  public IO_COUNTERS IoInfo;
72
45
  public UIntPtr ProcessMemoryLimit;
@@ -76,139 +49,165 @@ public class GeminiSandbox {
76
49
  }
77
50
 
78
51
  [StructLayout(LayoutKind.Sequential)]
79
- public struct SID_AND_ATTRIBUTES {
80
- public IntPtr Sid;
81
- public uint Attributes;
52
+ struct IO_COUNTERS {
53
+ public ulong ReadOperationCount;
54
+ public ulong WriteOperationCount;
55
+ public ulong OtherOperationCount;
56
+ public ulong ReadTransferCount;
57
+ public ulong WriteTransferCount;
58
+ public ulong OtherTransferCount;
82
59
  }
83
60
 
84
61
  [StructLayout(LayoutKind.Sequential)]
85
- public struct TOKEN_MANDATORY_LABEL {
86
- public SID_AND_ATTRIBUTES Label;
62
+ struct JOBOBJECT_NET_RATE_CONTROL_INFORMATION {
63
+ public ulong MaxBandwidth;
64
+ public uint ControlFlags;
65
+ public byte DscpTag;
87
66
  }
88
67
 
89
- public enum JobObjectInfoClass {
90
- ExtendedLimitInformation = 9
91
- }
68
+ [DllImport("kernel32.dll", SetLastError = true)]
69
+ static extern IntPtr CreateJobObject(IntPtr lpJobAttributes, string lpName);
70
+
71
+ [DllImport("kernel32.dll", SetLastError = true)]
72
+ static extern bool SetInformationJobObject(IntPtr hJob, int JobObjectInfoClass, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength);
92
73
 
93
74
  [DllImport("kernel32.dll", SetLastError = true)]
94
- public static extern IntPtr GetCurrentProcess();
75
+ static extern bool AssignProcessToJobObject(IntPtr hJob, IntPtr hProcess);
95
76
 
96
77
  [DllImport("advapi32.dll", SetLastError = true)]
97
- public static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle);
78
+ static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle);
98
79
 
99
80
  [DllImport("advapi32.dll", SetLastError = true)]
100
- public static extern bool CreateRestrictedToken(IntPtr ExistingTokenHandle, uint Flags, uint DisableSidCount, IntPtr SidsToDisable, uint DeletePrivilegeCount, IntPtr PrivilegesToDelete, uint RestrictedSidCount, IntPtr SidsToRestrict, out IntPtr NewTokenHandle);
81
+ static extern bool DuplicateTokenEx(IntPtr hExistingToken, uint dwDesiredAccess, IntPtr lpTokenAttributes, uint ImpersonationLevel, uint TokenType, out IntPtr phNewToken);
101
82
 
102
- [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
103
- public static extern bool CreateProcessAsUser(IntPtr hToken, string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
83
+ [DllImport("advapi32.dll", SetLastError = true)]
84
+ static extern bool CreateRestrictedToken(IntPtr ExistingTokenHandle, uint Flags, uint DisableSidCount, IntPtr SidsToDisable, uint DeletePrivilegeCount, IntPtr PrivilegesToDelete, uint RestrictedSidCount, IntPtr SidsToRestrict, out IntPtr NewTokenHandle);
104
85
 
105
- [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
106
- public static extern IntPtr CreateJobObject(IntPtr lpJobAttributes, string lpName);
86
+ [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
87
+ static extern bool CreateProcessAsUser(IntPtr hToken, string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
107
88
 
108
89
  [DllImport("kernel32.dll", SetLastError = true)]
109
- public static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoClass JobObjectInfoClass, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength);
90
+ static extern IntPtr GetCurrentProcess();
110
91
 
111
92
  [DllImport("kernel32.dll", SetLastError = true)]
112
- public static extern bool AssignProcessToJobObject(IntPtr hJob, IntPtr hProcess);
93
+ static extern bool CloseHandle(IntPtr hObject);
113
94
 
114
95
  [DllImport("kernel32.dll", SetLastError = true)]
115
- public static extern uint ResumeThread(IntPtr hThread);
96
+ static extern IntPtr GetStdHandle(int nStdHandle);
116
97
 
117
- [DllImport("kernel32.dll", SetLastError = true)]
118
- public static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);
98
+ [StructLayout(LayoutKind.Sequential)]
99
+ struct STARTUPINFO {
100
+ public uint cb;
101
+ public string lpReserved;
102
+ public string lpDesktop;
103
+ public string lpTitle;
104
+ public uint dwX;
105
+ public uint dwY;
106
+ public uint dwXSize;
107
+ public uint dwYSize;
108
+ public uint dwXCountChars;
109
+ public uint dwYCountChars;
110
+ public uint dwFillAttribute;
111
+ public uint dwFlags;
112
+ public short wShowWindow;
113
+ public short cbReserved2;
114
+ public IntPtr lpReserved2;
115
+ public IntPtr hStdInput;
116
+ public IntPtr hStdOutput;
117
+ public IntPtr hStdError;
118
+ }
119
119
 
120
- [DllImport("kernel32.dll", SetLastError = true)]
121
- public static extern bool GetExitCodeProcess(IntPtr hProcess, out uint lpExitCode);
120
+ [StructLayout(LayoutKind.Sequential)]
121
+ struct PROCESS_INFORMATION {
122
+ public IntPtr hProcess;
123
+ public IntPtr hThread;
124
+ public uint dwProcessId;
125
+ public uint dwThreadId;
126
+ }
122
127
 
123
- [DllImport("kernel32.dll", SetLastError = true)]
124
- public static extern bool CloseHandle(IntPtr hObject);
128
+ [DllImport("advapi32.dll", SetLastError = true)]
129
+ static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
125
130
 
126
- [DllImport("kernel32.dll", SetLastError = true)]
127
- public static extern IntPtr GetStdHandle(int nStdHandle);
131
+ [DllImport("advapi32.dll", SetLastError = true)]
132
+ static extern bool RevertToSelf();
133
+
134
+ [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
135
+ static extern uint GetLongPathName(string lpszShortPath, [Out] StringBuilder lpszLongPath, uint cchBuffer);
128
136
 
129
- [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
130
- public static extern bool ConvertStringSidToSid(string StringSid, out IntPtr Sid);
137
+ [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
138
+ static extern bool ConvertStringSidToSid(string StringSid, out IntPtr ptrSid);
131
139
 
132
140
  [DllImport("advapi32.dll", SetLastError = true)]
133
- public static extern bool SetTokenInformation(IntPtr TokenHandle, int TokenInformationClass, IntPtr TokenInformation, uint TokenInformationLength);
141
+ static extern bool SetTokenInformation(IntPtr TokenHandle, int TokenInformationClass, IntPtr TokenInformation, uint TokenInformationLength);
134
142
 
135
- [DllImport("kernel32.dll", SetLastError = true)]
136
- public static extern IntPtr LocalFree(IntPtr hMem);
137
-
138
- public const uint TOKEN_DUPLICATE = 0x0002;
139
- public const uint TOKEN_QUERY = 0x0008;
140
- public const uint TOKEN_ASSIGN_PRIMARY = 0x0001;
141
- public const uint TOKEN_ADJUST_DEFAULT = 0x0080;
142
- public const uint DISABLE_MAX_PRIVILEGE = 0x1;
143
- public const uint CREATE_SUSPENDED = 0x00000004;
144
- public const uint CREATE_UNICODE_ENVIRONMENT = 0x00000400;
145
- public const uint JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x00002000;
146
- public const uint STARTF_USESTDHANDLES = 0x00000100;
147
- public const int TokenIntegrityLevel = 25;
148
- public const uint SE_GROUP_INTEGRITY = 0x00000020;
149
- public const uint INFINITE = 0xFFFFFFFF;
143
+ [StructLayout(LayoutKind.Sequential)]
144
+ struct SID_AND_ATTRIBUTES {
145
+ public IntPtr Sid;
146
+ public uint Attributes;
147
+ }
148
+
149
+ [StructLayout(LayoutKind.Sequential)]
150
+ struct TOKEN_MANDATORY_LABEL {
151
+ public SID_AND_ATTRIBUTES Label;
152
+ }
153
+
154
+ private const int TokenIntegrityLevel = 25;
155
+ private const uint SE_GROUP_INTEGRITY = 0x00000020;
156
+ private const uint TOKEN_ALL_ACCESS = 0xF01FF;
157
+ private const uint DISABLE_MAX_PRIVILEGE = 0x1;
150
158
 
151
159
  static int Main(string[] args) {
152
160
  if (args.Length < 3) {
153
- Console.WriteLine("Usage: GeminiSandbox.exe <network:0|1> <cwd> <command> [args...]");
161
+ Console.WriteLine("Usage: GeminiSandbox.exe <network:0|1> <cwd> [--forbidden-manifest <path>] <command> [args...]");
154
162
  Console.WriteLine("Internal commands: __read <path>, __write <path>");
155
163
  return 1;
156
164
  }
157
165
 
158
166
  bool networkAccess = args[0] == "1";
159
167
  string cwd = args[1];
160
- string command = args[2];
168
+ HashSet<string> forbiddenPaths = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
169
+ int argIndex = 2;
170
+
171
+ if (argIndex < args.Length && args[argIndex] == "--forbidden-manifest") {
172
+ if (argIndex + 1 < args.Length) {
173
+ string manifestPath = args[argIndex + 1];
174
+ if (File.Exists(manifestPath)) {
175
+ foreach (string line in File.ReadAllLines(manifestPath)) {
176
+ if (!string.IsNullOrWhiteSpace(line)) {
177
+ forbiddenPaths.Add(GetNormalizedPath(line.Trim()));
178
+ }
179
+ }
180
+ }
181
+ argIndex += 2;
182
+ }
183
+ }
184
+
185
+ if (argIndex >= args.Length) {
186
+ Console.WriteLine("Error: Missing command");
187
+ return 1;
188
+ }
189
+
190
+ string command = args[argIndex];
161
191
 
162
192
  IntPtr hToken = IntPtr.Zero;
163
193
  IntPtr hRestrictedToken = IntPtr.Zero;
164
- IntPtr hJob = IntPtr.Zero;
165
- IntPtr pSidsToDisable = IntPtr.Zero;
166
- IntPtr pSidsToRestrict = IntPtr.Zero;
167
- IntPtr networkSid = IntPtr.Zero;
168
- IntPtr restrictedSid = IntPtr.Zero;
169
194
  IntPtr lowIntegritySid = IntPtr.Zero;
170
195
 
171
196
  try {
172
- // 1. Setup Token
173
- IntPtr hCurrentProcess = GetCurrentProcess();
174
- if (!OpenProcessToken(hCurrentProcess, TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_DEFAULT, out hToken)) {
175
- Console.Error.WriteLine("Failed to open process token");
197
+ // 1. Duplicate Primary Token
198
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, out hToken)) {
199
+ Console.WriteLine("Error: OpenProcessToken failed (" + Marshal.GetLastWin32Error() + ")");
176
200
  return 1;
177
201
  }
178
202
 
179
- uint sidCount = 0;
180
- uint restrictCount = 0;
181
-
182
- // "networkAccess == false" implies Strict Sandbox Level 1.
183
- if (!networkAccess) {
184
- if (ConvertStringSidToSid("S-1-5-2", out networkSid)) {
185
- sidCount = 1;
186
- int saaSize = Marshal.SizeOf(typeof(SID_AND_ATTRIBUTES));
187
- pSidsToDisable = Marshal.AllocHGlobal(saaSize);
188
- SID_AND_ATTRIBUTES saa = new SID_AND_ATTRIBUTES();
189
- saa.Sid = networkSid;
190
- saa.Attributes = 0;
191
- Marshal.StructureToPtr(saa, pSidsToDisable, false);
192
- }
193
-
194
- // S-1-5-12 is Restricted Code SID
195
- if (ConvertStringSidToSid("S-1-5-12", out restrictedSid)) {
196
- restrictCount = 1;
197
- int saaSize = Marshal.SizeOf(typeof(SID_AND_ATTRIBUTES));
198
- pSidsToRestrict = Marshal.AllocHGlobal(saaSize);
199
- SID_AND_ATTRIBUTES saa = new SID_AND_ATTRIBUTES();
200
- saa.Sid = restrictedSid;
201
- saa.Attributes = 0;
202
- Marshal.StructureToPtr(saa, pSidsToRestrict, false);
203
- }
204
- }
205
-
206
- if (!CreateRestrictedToken(hToken, DISABLE_MAX_PRIVILEGE, sidCount, pSidsToDisable, 0, IntPtr.Zero, restrictCount, pSidsToRestrict, out hRestrictedToken)) {
207
- Console.Error.WriteLine("Failed to create restricted token");
203
+ // Create a restricted token to strip administrative privileges
204
+ if (!CreateRestrictedToken(hToken, DISABLE_MAX_PRIVILEGE, 0, IntPtr.Zero, 0, IntPtr.Zero, 0, IntPtr.Zero, out hRestrictedToken)) {
205
+ Console.WriteLine("Error: CreateRestrictedToken failed (" + Marshal.GetLastWin32Error() + ")");
208
206
  return 1;
209
207
  }
210
208
 
211
- // 2. Set Integrity Level to Low
209
+ // 2. Lower Integrity Level to Low
210
+ // S-1-16-4096 is the SID for "Low Mandatory Level"
212
211
  if (ConvertStringSidToSid("S-1-16-4096", out lowIntegritySid)) {
213
212
  TOKEN_MANDATORY_LABEL tml = new TOKEN_MANDATORY_LABEL();
214
213
  tml.Label.Sid = lowIntegritySid;
@@ -217,154 +216,196 @@ public class GeminiSandbox {
217
216
  IntPtr pTml = Marshal.AllocHGlobal(tmlSize);
218
217
  try {
219
218
  Marshal.StructureToPtr(tml, pTml, false);
220
- SetTokenInformation(hRestrictedToken, TokenIntegrityLevel, pTml, (uint)tmlSize);
219
+ if (!SetTokenInformation(hRestrictedToken, TokenIntegrityLevel, pTml, (uint)tmlSize)) {
220
+ Console.WriteLine("Error: SetTokenInformation failed (" + Marshal.GetLastWin32Error() + ")");
221
+ return 1;
222
+ }
221
223
  } finally {
222
224
  Marshal.FreeHGlobal(pTml);
223
225
  }
224
226
  }
225
227
 
226
- // 3. Handle Internal Commands or External Process
228
+ // 3. Setup Job Object for cleanup
229
+ IntPtr hJob = CreateJobObject(IntPtr.Zero, null);
230
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobLimits = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION();
231
+ jobLimits.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION;
232
+
233
+ IntPtr lpJobLimits = Marshal.AllocHGlobal(Marshal.SizeOf(jobLimits));
234
+ Marshal.StructureToPtr(jobLimits, lpJobLimits, false);
235
+ SetInformationJobObject(hJob, 9 /* JobObjectExtendedLimitInformation */, lpJobLimits, (uint)Marshal.SizeOf(jobLimits));
236
+ Marshal.FreeHGlobal(lpJobLimits);
237
+
238
+ if (!networkAccess) {
239
+ JOBOBJECT_NET_RATE_CONTROL_INFORMATION netLimits = new JOBOBJECT_NET_RATE_CONTROL_INFORMATION();
240
+ netLimits.MaxBandwidth = 1;
241
+ netLimits.ControlFlags = 0x1 | 0x2; // ENABLE | MAX_BANDWIDTH
242
+ netLimits.DscpTag = 0;
243
+
244
+ IntPtr lpNetLimits = Marshal.AllocHGlobal(Marshal.SizeOf(netLimits));
245
+ Marshal.StructureToPtr(netLimits, lpNetLimits, false);
246
+ SetInformationJobObject(hJob, 32 /* JobObjectNetRateControlInformation */, lpNetLimits, (uint)Marshal.SizeOf(netLimits));
247
+ Marshal.FreeHGlobal(lpNetLimits);
248
+ }
249
+
250
+ // 4. Handle Internal Commands or External Process
227
251
  if (command == "__read") {
228
- string path = args[3];
252
+ if (argIndex + 1 >= args.Length) {
253
+ Console.WriteLine("Error: Missing path for __read");
254
+ return 1;
255
+ }
256
+ string path = args[argIndex + 1];
257
+ CheckForbidden(path, forbiddenPaths);
229
258
  return RunInImpersonation(hRestrictedToken, () => {
230
259
  try {
231
260
  using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
232
- using (StreamReader sr = new StreamReader(fs, System.Text.Encoding.UTF8)) {
233
- char[] buffer = new char[4096];
234
- int bytesRead;
235
- while ((bytesRead = sr.Read(buffer, 0, buffer.Length)) > 0) {
236
- Console.Write(buffer, 0, bytesRead);
237
- }
261
+ using (Stream stdout = Console.OpenStandardOutput()) {
262
+ fs.CopyTo(stdout);
238
263
  }
239
264
  return 0;
240
265
  } catch (Exception e) {
241
- Console.Error.WriteLine(e.Message);
266
+ Console.Error.WriteLine("Error reading file: " + e.Message);
242
267
  return 1;
243
268
  }
244
269
  });
245
270
  } else if (command == "__write") {
246
- string path = args[3];
271
+ if (argIndex + 1 >= args.Length) {
272
+ Console.WriteLine("Error: Missing path for __write");
273
+ return 1;
274
+ }
275
+ string path = args[argIndex + 1];
276
+ CheckForbidden(path, forbiddenPaths);
247
277
  return RunInImpersonation(hRestrictedToken, () => {
248
278
  try {
249
279
  using (StreamReader reader = new StreamReader(Console.OpenStandardInput(), System.Text.Encoding.UTF8))
250
280
  using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
251
281
  using (StreamWriter writer = new StreamWriter(fs, System.Text.Encoding.UTF8)) {
252
- char[] buffer = new char[4096];
253
- int bytesRead;
254
- while ((bytesRead = reader.Read(buffer, 0, buffer.Length)) > 0) {
255
- writer.Write(buffer, 0, bytesRead);
256
- }
282
+ writer.Write(reader.ReadToEnd());
257
283
  }
258
284
  return 0;
259
285
  } catch (Exception e) {
260
- Console.Error.WriteLine(e.Message);
286
+ Console.Error.WriteLine("Error writing file: " + e.Message);
261
287
  return 1;
262
288
  }
263
289
  });
264
290
  }
265
291
 
266
- // 4. Setup Job Object for external process
267
- hJob = CreateJobObject(IntPtr.Zero, null);
268
- if (hJob != IntPtr.Zero) {
269
- JOBOBJECT_EXTENDED_LIMIT_INFORMATION limitInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION();
270
- limitInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
271
- int limitSize = Marshal.SizeOf(limitInfo);
272
- IntPtr pLimit = Marshal.AllocHGlobal(limitSize);
273
- try {
274
- Marshal.StructureToPtr(limitInfo, pLimit, false);
275
- SetInformationJobObject(hJob, JobObjectInfoClass.ExtendedLimitInformation, pLimit, (uint)limitSize);
276
- } finally {
277
- Marshal.FreeHGlobal(pLimit);
278
- }
279
- }
280
-
281
- // 5. Launch Process
292
+ // External Process
282
293
  STARTUPINFO si = new STARTUPINFO();
283
294
  si.cb = (uint)Marshal.SizeOf(si);
284
- si.dwFlags = STARTF_USESTDHANDLES;
295
+ si.dwFlags = 0x00000100; // STARTF_USESTDHANDLES
285
296
  si.hStdInput = GetStdHandle(-10);
286
297
  si.hStdOutput = GetStdHandle(-11);
287
298
  si.hStdError = GetStdHandle(-12);
288
299
 
289
300
  string commandLine = "";
290
- for (int i = 2; i < args.Length; i++) {
291
- if (i > 2) commandLine += " ";
301
+ for (int i = argIndex; i < args.Length; i++) {
302
+ if (i > argIndex) commandLine += " ";
292
303
  commandLine += QuoteArgument(args[i]);
293
304
  }
294
305
 
295
- PROCESS_INFORMATION pi;
296
- if (!CreateProcessAsUser(hRestrictedToken, null, commandLine, IntPtr.Zero, IntPtr.Zero, true, CREATE_SUSPENDED | CREATE_UNICODE_ENVIRONMENT, IntPtr.Zero, cwd, ref si, out pi)) {
297
- Console.Error.WriteLine("Failed to create process. Error: " + Marshal.GetLastWin32Error());
306
+ PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
307
+ // Creation Flags: 0x04000000 (CREATE_BREAKAWAY_FROM_JOB) to allow job assignment if parent is in job
308
+ uint creationFlags = 0;
309
+ if (!CreateProcessAsUser(hRestrictedToken, null, commandLine, IntPtr.Zero, IntPtr.Zero, true, creationFlags, IntPtr.Zero, cwd, ref si, out pi)) {
310
+ Console.WriteLine("Error: CreateProcessAsUser failed (" + Marshal.GetLastWin32Error() + ") Command: " + commandLine);
298
311
  return 1;
299
312
  }
300
313
 
301
- try {
302
- if (hJob != IntPtr.Zero) {
303
- AssignProcessToJobObject(hJob, pi.hProcess);
304
- }
314
+ AssignProcessToJobObject(hJob, pi.hProcess);
315
+
316
+ // Wait for exit
317
+ uint waitResult = WaitForSingleObject(pi.hProcess, 0xFFFFFFFF);
318
+ uint exitCode = 0;
319
+ GetExitCodeProcess(pi.hProcess, out exitCode);
305
320
 
306
- ResumeThread(pi.hThread);
307
- WaitForSingleObject(pi.hProcess, INFINITE);
321
+ CloseHandle(pi.hProcess);
322
+ CloseHandle(pi.hThread);
323
+ CloseHandle(hJob);
308
324
 
309
- uint exitCode = 0;
310
- GetExitCodeProcess(pi.hProcess, out exitCode);
311
- return (int)exitCode;
312
- } finally {
313
- CloseHandle(pi.hProcess);
314
- CloseHandle(pi.hThread);
315
- }
316
- } catch (Exception e) {
317
- Console.Error.WriteLine("Unexpected error: " + e.Message);
318
- return 1;
325
+ return (int)exitCode;
319
326
  } finally {
320
- if (hRestrictedToken != IntPtr.Zero) CloseHandle(hRestrictedToken);
321
327
  if (hToken != IntPtr.Zero) CloseHandle(hToken);
322
- if (hJob != IntPtr.Zero) CloseHandle(hJob);
323
- if (pSidsToDisable != IntPtr.Zero) Marshal.FreeHGlobal(pSidsToDisable);
324
- if (pSidsToRestrict != IntPtr.Zero) Marshal.FreeHGlobal(pSidsToRestrict);
325
- if (networkSid != IntPtr.Zero) LocalFree(networkSid);
326
- if (restrictedSid != IntPtr.Zero) LocalFree(restrictedSid);
327
- if (lowIntegritySid != IntPtr.Zero) LocalFree(lowIntegritySid);
328
+ if (hRestrictedToken != IntPtr.Zero) CloseHandle(hRestrictedToken);
329
+ }
330
+ }
331
+
332
+ [DllImport("kernel32.dll", SetLastError = true)]
333
+ static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);
334
+
335
+ [DllImport("kernel32.dll", SetLastError = true)]
336
+ static extern bool GetExitCodeProcess(IntPtr hProcess, out uint lpExitCode);
337
+
338
+ private static int RunInImpersonation(IntPtr hToken, Func<int> action) {
339
+ if (!ImpersonateLoggedOnUser(hToken)) {
340
+ Console.WriteLine("Error: ImpersonateLoggedOnUser failed (" + Marshal.GetLastWin32Error() + ")");
341
+ return 1;
342
+ }
343
+ try {
344
+ return action();
345
+ } finally {
346
+ RevertToSelf();
347
+ }
348
+ }
349
+
350
+ private static string GetNormalizedPath(string path) {
351
+ string fullPath = Path.GetFullPath(path);
352
+ StringBuilder longPath = new StringBuilder(1024);
353
+ uint result = GetLongPathName(fullPath, longPath, (uint)longPath.Capacity);
354
+ if (result > 0 && result < longPath.Capacity) {
355
+ return longPath.ToString();
356
+ }
357
+ return fullPath;
358
+ }
359
+
360
+ private static void CheckForbidden(string path, HashSet<string> forbiddenPaths) {
361
+ string fullPath = GetNormalizedPath(path);
362
+ foreach (string forbidden in forbiddenPaths) {
363
+ if (fullPath.Equals(forbidden, StringComparison.OrdinalIgnoreCase) || fullPath.StartsWith(forbidden + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase)) {
364
+ throw new UnauthorizedAccessException("Access to forbidden path is denied: " + path);
365
+ }
328
366
  }
329
367
  }
330
368
 
331
369
  private static string QuoteArgument(string arg) {
332
370
  if (string.IsNullOrEmpty(arg)) return "\"\"";
333
371
 
334
- bool hasSpace = arg.IndexOfAny(new char[] { ' ', '\t' }) != -1;
335
- if (!hasSpace && arg.IndexOf('\"') == -1) return arg;
372
+ bool needsQuotes = false;
373
+ foreach (char c in arg) {
374
+ if (char.IsWhiteSpace(c) || c == '\"') {
375
+ needsQuotes = true;
376
+ break;
377
+ }
378
+ }
379
+
380
+ if (!needsQuotes) return arg;
336
381
 
337
- // Windows command line escaping for arguments is complex.
338
- // Rule: Backslashes only need escaping if they precede a double quote or the end of the string.
339
- System.Text.StringBuilder sb = new System.Text.StringBuilder();
382
+ StringBuilder sb = new StringBuilder();
340
383
  sb.Append('\"');
341
384
  for (int i = 0; i < arg.Length; i++) {
342
- int backslashCount = 0;
343
- while (i < arg.Length && arg[i] == '\\') {
344
- backslashCount++;
345
- i++;
346
- }
385
+ char c = arg[i];
386
+ if (c == '\"') {
387
+ sb.Append("\\\"");
388
+ } else if (c == '\\') {
389
+ int backslashCount = 0;
390
+ while (i < arg.Length && arg[i] == '\\') {
391
+ backslashCount++;
392
+ i++;
393
+ }
347
394
 
348
- if (i == arg.Length) {
349
- // Escape backslashes before the closing double quote
350
- sb.Append('\\', backslashCount * 2);
351
- } else if (arg[i] == '\"') {
352
- // Escape backslashes before a literal double quote
353
- sb.Append('\\', backslashCount * 2 + 1);
354
- sb.Append('\"');
395
+ if (i == arg.Length) {
396
+ sb.Append('\\', backslashCount * 2);
397
+ } else if (arg[i] == '\"') {
398
+ sb.Append('\\', backslashCount * 2 + 1);
399
+ sb.Append('\"');
400
+ } else {
401
+ sb.Append('\\', backslashCount);
402
+ sb.Append(arg[i]);
403
+ }
355
404
  } else {
356
- // Backslashes don't need escaping here
357
- sb.Append('\\', backslashCount);
358
- sb.Append(arg[i]);
405
+ sb.Append(c);
359
406
  }
360
407
  }
361
408
  sb.Append('\"');
362
409
  return sb.ToString();
363
410
  }
364
-
365
- private static int RunInImpersonation(IntPtr hToken, Func<int> action) {
366
- using (WindowsIdentity.Impersonate(hToken)) {
367
- return action();
368
- }
369
- }
370
411
  }
@@ -3,7 +3,8 @@
3
3
  * Copyright 2026 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { type SandboxManager, type SandboxRequest, type SandboxedCommand, type GlobalSandboxOptions } from '../../services/sandboxManager.js';
6
+ import { type SandboxManager, type SandboxRequest, type SandboxedCommand, type GlobalSandboxOptions, type ParsedSandboxDenial } from '../../services/sandboxManager.js';
7
+ import type { ShellExecutionResult } from '../../services/shellExecutionService.js';
7
8
  /**
8
9
  * A SandboxManager implementation for Windows that uses Restricted Tokens,
9
10
  * Job Objects, and Low Integrity levels for process isolation.
@@ -13,8 +14,12 @@ export declare class WindowsSandboxManager implements SandboxManager {
13
14
  private readonly options;
14
15
  private readonly helperPath;
15
16
  private initialized;
16
- private readonly lowIntegrityCache;
17
+ private readonly allowedCache;
18
+ private readonly deniedCache;
17
19
  constructor(options: GlobalSandboxOptions);
20
+ isKnownSafeCommand(args: string[]): boolean;
21
+ isDangerousCommand(args: string[]): boolean;
22
+ parseDenials(result: ShellExecutionResult): ParsedSandboxDenial | undefined;
18
23
  /**
19
24
  * Ensures a file or directory exists.
20
25
  */
@@ -28,4 +33,9 @@ export declare class WindowsSandboxManager implements SandboxManager {
28
33
  * Grants "Low Mandatory Level" access to a path using icacls.
29
34
  */
30
35
  private grantLowIntegrityAccess;
36
+ /**
37
+ * Explicitly denies access to a path for Low Integrity processes using icacls.
38
+ */
39
+ private denyLowIntegrityAccess;
40
+ private isSystemDirectory;
31
41
  }